This guide is for maintainers, forkers, translators, and anyone running an editorial operation on the Front-End Checklist. The subject is the repository, not a running service. There is no daemon, no API, no deployment — the product is one Markdown file (README.md) served by GitHub, supported by five small configuration files (.editorconfig, .prettierrc, .markdownlint.json, lychee.toml, package.json) that govern its editorial pipeline.
The sections below cover the document's architecture, the build-support tooling (Prettier + markdownlint + Lychee + Husky), the contribution and review workflow, the translation-fork model, the licensing nuances, the issue-triage reality, the security considerations for a pure-content repo, and the derivative playbook for anyone who wants to build an adjacent checklist. Everything is sourced from the repo at commit 09d56df (2025-02-14).
Important
This is not software you operate. It is a document you publish. "Operations" in this guide means editorial operations: accepting PRs, reviewing items, rotating broken links, honoring the Code of Conduct, keeping the translation-fork list accurate, and maintaining the link-check pipeline.
Table of Contents
- Architecture Overview
- System Requirements
- Configuration Reference
- Deployment & Scaling
- Operations
- Performance
- Security
- Developer Internals
- Integration Points
1. Architecture Overview
1.1 Executive summary
| Field | Value |
|---|---|
| Upstream | github.com/thedaviddias/Front-End-Checklist |
| Primary maintainer | David Dias (thedaviddias) |
License (LICENSE file) |
CC0 1.0 Universal (public-domain dedication) |
License (package.json field) |
CC-BY-4.0 — conflicts with LICENSE; see §7.4 |
| Default branch | main |
| Documented source commit | 09d56df (2025-02-14) |
| Total tracked files | 15 |
| Source code | 0 lines — this is a content repo |
| Primary artifact | README.md |
| Secondary artifacts | CONTRIBUTING.md, CODE_OF_CONDUCT.md, LICENSE, 3 priority SVG badges, 1 project logo |
| Build system | None in the "producing an output" sense |
| Tooling dependencies | prettier@^3.3.3, markdownlint-cli@^0.42.0, husky@^9.1.6 (devDependencies only) |
| Link-checker | Lychee (configured by lychee.toml, runs in CI) |
| Package manager | pnpm (pnpm-lock.yaml is committed) |
| Sibling repos | Front-End-Performance-Checklist, Front-End-Design-Checklist |
| Translations | 13 community forks |
| Funding | OpenCollective (opencollective.com/front-end-checklist) |
| Public support | X, Discord |
| Security / CoC contact | [email removed] (per CODE_OF_CONDUCT.md) |
1.2 What the system does
The Front-End Checklist publishes a curated, priority-tagged list of pre-launch verifications that front-end developers, QA engineers, and tech leads run against a website before it goes to production. The "system" is:
- A
README.mdfile (the product) — read on the GitHub repo landing page or any Markdown viewer. - Five tooling files that enforce editorial consistency on every PR (
.editorconfig,.prettierrc,.markdownlint.json,lychee.toml,package.json). - A community editorial process — Issues, PRs, translation forks, OpenCollective backers — operated by a single primary maintainer.
There is no runtime, no compilation, no deployment in the software-engineering sense. Releases are git commits. Distribution is GitHub's CDN (raw.githubusercontent.com for the SVG assets, the GitHub web UI for the rendered Markdown).
1.3 Repository tree
Front-End-Checklist/
├── .editorconfig # Universal whitespace / charset / EOL rules
├── .gitignore # Node-flavoured ignore list (node_modules, lychee-out.md, etc.)
├── .markdownlint.json # markdownlint rule overrides
├── .prettierrc # Prettier config, with Markdown-specific override
├── CODE_OF_CONDUCT.md # Contributor Covenant v1.4
├── CONTRIBUTING.md # Contribution guide (QA, Marketing, Community, Code, Money)
├── LICENSE # Creative Commons CC0 1.0 Universal
├── README.md # THE PRODUCT — the checklist itself
├── data/
│ └── images/
│ ├── logo-front-end-checklist.jpg
│ └── priority/
│ ├── high.svg # Red dot badge
│ ├── low.svg # Green dot badge
│ └── medium.svg # Orange dot badge
├── lychee.toml # Link-checker configuration
├── package.json # Node manifest — solely for devtools
└── pnpm-lock.yaml # pnpm lockfile (pinned devDependency versions)
15 tracked files total. No source code, no build output, no cached artifacts.
1.4 Component inventory
| Component | Path | Role |
|---|---|---|
| The checklist | README.md |
The product |
| Contribution guide | CONTRIBUTING.md |
How outside developers contribute |
| Conduct policy | CODE_OF_CONDUCT.md |
Contributor Covenant v1.4, with [email removed] as the report channel |
| License (legal) | LICENSE |
CC0 1.0 Universal full text |
| Priority badges | data/images/priority/{high,medium,low}.svg |
Three coloured dot SVGs referenced inline by ![High][high_img] style references |
| Project logo | data/images/logo-front-end-checklist.jpg |
Used in the README header |
| EditorConfig | .editorconfig |
Cross-editor whitespace/encoding rules |
| Prettier config | .prettierrc |
Markdown reflow rules |
| markdownlint config | .markdownlint.json |
Three rule overrides |
| Lychee config | lychee.toml |
Link-checker rules |
| Node manifest | package.json |
Three dev scripts; three devDependencies; no runtime dependencies |
| pnpm lockfile | pnpm-lock.yaml |
Pinned devDependency tree |
| Git ignore | .gitignore |
Standard Node + IDE ignores plus lychee-out.md |
1.5 Content architecture
The document itself is the architecture. README.md is a strictly hierarchical flat-section document:
H1 🗂 Front-End Checklist (one H1 — the document title)
├── H2 📚 Table of Contents
├── H2 How to use?
├── H2 Head
│ ├── H3 Meta tag
│ ├── H3 HTML tags
│ └── H3 Social meta
├── H2 HTML
│ ├── H3 Best practices
│ └── H3 HTML testing
├── H2 Webfonts
├── H2 CSS
│ ├── H3 Performance
│ └── H3 CSS testing
├── H2 Images
│ └── H3 Best practices
├── H2 JavaScript
│ ├── H3 Best practices
│ └── H3 JavaScript testing
├── H2 Security
│ ├── H3 Scan and check your web site
│ └── H3 Best practices
├── H2 Performance
│ ├── H3 Best practices
│ ├── H3 Preparing upcoming requests
│ └── H3 Performance testing
├── H2 Accessibility
│ ├── H3 Best practices
│ ├── H3 Headings (contains H4 subheadings)
│ ├── H3 Semantics
│ ├── H3 Form
│ └── H3 Accessibility testing
├── H2 SEO
├── H2 Translations
├── H2 Support
├── H2 Contributors
├── H2 Backers
├── H2 Sponsors
└── H2 License
Each H3 contains a flat list of - [ ] **Label:** ![Priority][priority_img] rationale. items, optionally with code blocks (wrapped in <!-- prettier-ignore-start --> / <!-- prettier-ignore-end --> guards) and emoji-prefixed reference bullets (- 📖, - 🛠, - 📹).
Note
The checklist's design rationale is predictable scannability: every category, every subsection, every item follows the same micro-structure. A reviewer who scanned a previous launch can scan a new one in half the time. The hand-maintained nature creates occasional formatting drift; markdownlint and the §5 review rubric exist to catch it.
1.6 The three-part item contract
- [ ] **<Label>:** ![<Tier>][<tier>_img] <one-or-two-line rationale>.
```<lang>
<optional code example>
- <emoji> <link title>
- <emoji> <link title>
Deviations from this contract are rare content-quality bugs; see §5.2 for review criteria.
### 1.7 Priority-image link-reference pattern
The three priority images are defined once at the **bottom** of `README.md` as Markdown link references:
```markdown
[low_img]: https://raw.githubusercontent.com/thedaviddias/Front-End-Checklist/refs/heads/main/data/images/priority/low.svg
[medium_img]: https://raw.githubusercontent.com/thedaviddias/Front-End-Checklist/refs/heads/main/data/images/priority/medium.svg
[high_img]: https://raw.githubusercontent.com/thedaviddias/Front-End-Checklist/refs/heads/main/data/images/priority/high.svg
Every item then cites them by label (![High][high_img]). This keeps inline markup tidy and lets the maintainer change the badge URL in one place.
Note
The URLs point at
raw.githubusercontent.com/...refs/heads/main/..., notrefs/tags/.... If a future maintainer renames the default branch or moves the SVGs, every inline badge across every translation fork breaks. Consider pinning to a commit SHA or hosting via GitHub Pages for durability — see §8.5 Potential Improvements.
1.8 GitHub Linguist classification
The repo has no .gitattributes overriding GitHub's language detection. Linguist sees README.md plus a few .json config files plus SVGs and classifies the repo as 100 % Markdown / 0 % code. This is correct — there is no code.
If a future maintainer wants the repo to surface in "JavaScript" or "HTML" GitHub repo searches (for discoverability), they can add a .gitattributes:
*.md linguist-detectable=true
*.md linguist-documentation=false
*.md linguist-language=HTML
Warning
Overriding Linguist is a discoverability lever, not an honest classification. Only do it if the repo is primarily consumed by a target-language community currently hidden by the Markdown label.
2. System Requirements
The repo's only operational concern is the editorial tooling that maintainers run before merging PRs.
2.1 For readers
None. Open a browser, or clone the repo and open README.md in any editor.
2.2 For contributors (running the dev tooling)
| Component | Required | Version | Notes |
|---|---|---|---|
| Node.js | Yes | Any LTS (20.x, 22.x verified against devDependencies' Node engines) | No engines field in package.json, so any reasonably modern Node works |
| pnpm | Recommended | ≥ 8 | pnpm-lock.yaml is the authoritative lockfile; npm install works but writes a competing package-lock.json |
| Git | Yes | Any | Needed for Husky hooks and normal repo operations |
| Lychee | Yes if running link-check locally | ≥ 0.15 | Not a package.json dependency — install as a standalone binary (cargo, brew, or pre-built release) |
| A Markdown viewer | For authoring | n/a | VS Code, Typora, Obsidian, grip — any works |
2.3 For forkers / translators
A GitHub account and a clone of the upstream repo. No other tooling required unless you want to run Lychee against your translation.
2.4 For maintainers
Same as contributors plus:
- Repo
adminaccess on GitHub. - Access to the
[email removed]mailbox (for CoC reports and security disclosures). - An OpenCollective owner account if the maintainer rotates funding distribution.
2.5 Storage and bandwidth
The repo is ~5 MB cloned. The README is ~29 KB and ~850 lines. Lychee link-checks ~310 external URLs per run; with accept = ["200", "429", "403"] and max_concurrency = 14, a full run completes in roughly 30-60 seconds depending on external service latency.
3. Configuration Reference
Every configuration file in the repo, what it controls, and its exact current value.
3.1 .editorconfig
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
Effect: any EditorConfig-aware editor (VS Code, JetBrains, Vim with plugin, Sublime with plugin) opens files with these settings by default. Guarantees cross-editor consistency on whitespace and line endings.
| Key | Value | Why |
|---|---|---|
charset |
utf-8 |
Required for emoji and non-ASCII language content in translation forks |
indent_style |
space |
Avoids tab/space mixing in YAML / JSON / Markdown code blocks |
indent_size |
2 |
Common JS-ecosystem default |
end_of_line |
lf |
Required for cross-platform diff cleanliness; Prettier also sets this |
insert_final_newline |
true |
POSIX-compliant file ending |
trim_trailing_whitespace |
true |
Keeps diffs small |
3.2 .prettierrc
{
"trailingComma": "none",
"tabWidth": 2,
"semi": true,
"singleQuote": true,
"printWidth": 150,
"endOfLine": "lf",
"overrides": [
{
"files": "*.md",
"options": {
"htmlWhitespaceSensitivity": "ignore",
"proseWrap": "preserve",
"embeddedLanguageFormatting": "off"
}
}
]
}
| Key | Value | Effect |
|---|---|---|
trailingComma |
none |
No trailing commas in JS / JSON / TS — unusual for modern projects but intentional |
tabWidth |
2 |
Matches .editorconfig |
semi |
true |
Terminate statements with ; (JS / TS only) |
singleQuote |
true |
'text' preferred over "text" in JS / TS |
printWidth |
150 |
Very wide — accommodates long Markdown lines with inline badges and URLs |
endOfLine |
lf |
Matches .editorconfig |
overrides.files = *.md |
Markdown-only overrides follow | |
htmlWhitespaceSensitivity |
ignore |
Allows Prettier to reflow HTML code blocks without fearing render drift |
proseWrap |
preserve |
Respects hand-crafted line breaks in prose — critical for this repo's formatting |
embeddedLanguageFormatting |
off |
Prettier does not format inner HTML/JS/CSS inside Markdown code blocks |
Important
proseWrap: "preserve"is why the README keeps its existing line wraps. If a future maintainer changes this to"always", Prettier will reflow every prose paragraph and produce an enormous PR touching thousands of lines. Do not change this casually — the change is irreversible without a manual re-flow pass.
The <!-- prettier-ignore-start --> / <!-- prettier-ignore-end --> comments scattered through the README further disable Prettier on specific HTML code blocks that Prettier would otherwise reformat in ways that hurt readability.
3.3 .markdownlint.json
{
"MD013": false,
"MD024": false,
"MD033": false
}
| Rule | Name | Status | Why |
|---|---|---|---|
MD013 |
line-length |
Disabled | The checklist routinely has lines far longer than 80 / 100 / 120 chars (inline image badges + long rationale) |
MD024 |
no-duplicate-header |
Disabled | The README intentionally repeats "Best practices", "HTML testing", "CSS testing" headings across categories |
MD033 |
no-inline-html |
Disabled | The README uses inline HTML for <a>, <img>, <br>, and OpenCollective banner images |
All other markdownlint rules are on defaults. A violation of any non-disabled rule blocks pnpm format:fix from completing clean.
3.4 lychee.toml
############################# Display #############################
verbose = "info"
output = "./lychee-out.md"
############################# Cache ###############################
cache = true
max_cache_age = "2d"
############################# Runtime #############################
max_concurrency = 14
############################# Requests ############################
user_agent = "curl/7.83.1"
timeout = 20
accept = ["200", "429", "403"]
scheme = ["https"]
############################# Exclusions ##########################
base = "https://github.com/thedaviddias/Front-End-Checklist/"
exclude = ["https://caniuse.com"]
| Key | Value | Why |
|---|---|---|
verbose |
info |
Balanced logging — fewer false-positive noise |
output |
./lychee-out.md |
Link-check report written to root; .gitignore excludes it |
cache |
true |
Avoids hitting the same URL twice within the cache window |
max_cache_age |
2d |
Rechecks links at least every 2 days in CI |
max_concurrency |
14 |
Parallel HTTP fetchers — a compromise between speed and politeness |
user_agent |
curl/7.83.1 |
Some CDN/cache layers 403 unfamiliar UAs; pretending to be curl maximizes success |
timeout |
20 |
Seconds per request — forgiving enough for slow archives |
accept |
[200, 429, 403] |
Treat 429 (rate-limit) and 403 (auth-walled but existent) as OK. Prevents false failures on Google and GitHub URLs |
scheme |
["https"] |
Only HTTPS URLs are checked (insecure http:// links flagged separately) |
base |
https://github.com/thedaviddias/Front-End-Checklist/ |
Base URL for relative links |
exclude |
["https://caniuse.com"] |
caniuse.com's anti-bot layer is flaky; excluded to reduce CI churn |
Note
Treating
403and429as OK is a trade-off: it avoids CI flakiness on auth-walled or rate-limited resources, but hides the case where a tool has been fully deprecated and now returns a genuine 403 "gone" forever. Review the full Lychee report periodically, not just the pass/fail exit code.
3.5 package.json
{
"name": "front-end-checklist",
"version": "1.0.0",
"description": "The perfect Front-End Checklist for modern websites and meticulous developers",
"scripts": {
"format:check": "prettier --check README.md",
"format:fix": "prettier --write README.md && markdownlint README.md",
"prepare": "husky || true"
},
"keywords": ["front-end", "checklist", "html", "css", "javascript", "accessibility",
"lists", "developer", "developer-tools"],
"author": "David Dias (https://thedaviddias.com/)",
"license": "CC-BY-4.0",
"devDependencies": {
"husky": "^9.1.6",
"markdownlint-cli": "^0.42.0",
"prettier": "^3.3.3"
}
}
Scripts:
| Script | Command | Purpose |
|---|---|---|
format:check |
prettier --check README.md |
CI gate: fails if the README is not Prettier-clean |
format:fix |
prettier --write README.md && markdownlint README.md |
Apply Prettier, then run markdownlint (non-fixing) |
prepare |
husky || true |
Install Husky git hooks on pnpm install; || true prevents failure when Husky is not installed (e.g. CI caches) |
Important
License-field mismatch: the
licensefield reads"CC-BY-4.0", but the actualLICENSEfile contains Creative Commons CC0 1.0 Universal text. These are not the same license. TheLICENSEfile is legally authoritative; see §7.4. The fix is to change the field to"CC0-1.0"— see §8.5 Potential Improvements.
devDependencies only: there are no production dependencies. The package would not be publishable to npm as-is (no main or exports field, no runtime code), which is intentional.
3.6 .gitignore and pnpm-lock.yaml
.gitignore follows standard Node + IDE ignores (node_modules/, *.log, .DS_Store, editor scratch dirs) plus lychee-out.md to keep the link-check output untracked.
pnpm-lock.yaml pins the three devDependencies and their transitive graph (~80 packages). Regenerate on intentional dependency bumps with pnpm install after updating package.json.
4. Deployment & Scaling
There is no deployment in the runtime sense. "Deployment" is git push to main; "scaling" is editorial bandwidth, not server capacity.
4.1 The release model
contributor opens PR
↓
CI: pnpm format:check (Prettier)
↓
CI: lychee --config lychee.toml README.md (Link-check)
↓
maintainer review (manual)
↓
merge to main
↓
GitHub serves README.md from main (no further deploy step)
GitHub's CDN handles serving and caching. New translation forks, new sibling derivatives, and new app integrations are someone else's deployment problem — the upstream repo is the source.
4.2 Distribution surfaces
| Surface | URL pattern | Cache behavior |
|---|---|---|
| GitHub repo landing page | github.com/thedaviddias/Front-End-Checklist |
GitHub-controlled, ~5-minute edge cache for README rendering |
| Raw README | raw.githubusercontent.com/thedaviddias/Front-End-Checklist/main/README.md |
~5-minute edge cache; updated quickly on push |
| Priority SVG badges | raw.githubusercontent.com/.../data/images/priority/{high,medium,low}.svg |
Same as raw README |
| OpenCollective banners | opencollective.com/front-end-checklist/... |
OpenCollective-controlled |
| Issues / PRs page | github.com/thedaviddias/Front-End-Checklist/issues |
Live |
4.3 Editorial scaling
The bottleneck is reviewer time, not infrastructure. Strategies that increase merge throughput:
- [ ] Add
.github/ISSUE_TEMPLATE/to filter low-quality issues at submission. - [ ] Add
.github/pull_request_template.mdwith the §5.2 review rubric as a contributor self-checklist. - [ ] Adopt a "two-maintainer" model: grant
triageaccess to a trusted contributor who can label and close noise issues without merge rights. - [ ] Quarterly link-rot sweeps (a single maintainer, one sitting per quarter) instead of one-PR-per-broken-link.
4.4 Translation distribution
Translations live as independent forks, each under a different user account. The upstream's only "distribution" responsibility is the list of fork URLs in the Translations section of README.md. Adding a new translation is a tiny PR; removing one is also a tiny PR. There is no synchronization requirement — translation forks drift, and that is acceptable.
Tip
If translation drift becomes a real problem, build (or commission) a small bot that produces a weekly diff between upstream
mainand each fork'sREADME.md, posted as a comment on a tracking issue. The cost is one GitHub Action workflow file plus a personal-access token; the benefit is translators get a nudge without the upstream maintainer having to chase.
4.5 Sibling-repo coordination
The author maintains two siblings: Front-End-Performance-Checklist and Front-End-Design-Checklist. All three use almost identical structure and tooling, which means a tooling improvement (for example, adding a GitHub Action to run Lychee in CI) should ideally be applied to all three repos at once. Maintain a personal "siblings checklist" so changes propagate.
5. Operations
The day-to-day editorial operations of the repo.
5.1 Triage an incoming issue
First-pass classification:
1. Content bug → label "bug", assign priority
2. New-item request → label "enhancement", evaluate per §5.2 rubric
3. Translation request → reply with fork instructions (see §9.3), close as NOT-PLANNED
4. Broken link report → label "link-rot", add to next Lychee batch fix
5. Off-topic / noise → close politely; consider adding an ISSUE_TEMPLATE
6. CoC violation → enforce per CODE_OF_CONDUCT.md
| Symptom | Action |
|---|---|
| Issue title has no sentence structure ("Ui", "Hi", "Virus?!?") | Ask for clarification once; close if no response within 2 weeks |
| Issue requests a translation | Paste the fork instructions (§9.3); close |
| Issue reports a broken link | Reproduce locally with lychee --config lychee.toml README.md, fix in next PR |
| Issue proposes a new checklist item | Apply the §5.2 review rubric |
| Issue reports a duplicated paragraph / typo | Fix in a one-line PR |
| Issue is a security false positive ("is this a virus?") | Reply with the facts (the repo contains only Markdown, SVG, config); close |
Real examples from the issue history at 09d56df:
| Issue | Type | Disposition |
|---|---|---|
| #694 (OPEN) FileShot.io | Self-promotion | Evaluate under §5.2; likely close |
| #688, #686 API INTEGRATION | Off-topic | Closed |
| #687 "Ui" | Empty issue | Closed |
| #683 Accessibility improvements | Enhancement | Closed |
| #549 "Virus?!?" | False positive | Closed |
| #522 Paragraph repeats | Content bug | Closed (fix merged) |
| #521 GA Checker link invalid | Link rot | Closed |
| #511 Persian Translation | Fork request | Closed with fork instructions |
Note
Eight out of the ten most recent issues at commit
09d56dfwere either off-topic (API integration, "Ui", empty issues) or false positives (virus scanner). An ISSUE_TEMPLATE filter would have suppressed roughly half of them. See §8.5 Potential Improvements.
5.2 Review a content pull request
A new - [ ] **Label:** ![Tier][tier_img] rationale. line should satisfy all of:
- [ ] Truly front-end. Backend, deployment, and infrastructure items belong elsewhere.
- [ ] Verifiable. A reviewer can tick the item with a concrete check (a tool, a browser inspection, a manual test).
- [ ] Not already covered. Grep
README.mdfor overlap before merging. - [ ] Correct priority tier. Low = omit freely; Medium = omit only with reason; High = mandatory. Author's judgment; reviewer pushes back if clearly wrong.
- [ ] Rationale ≤ 2 lines. If it needs more explanation, link a 📖 source instead of prose-dumping.
- [ ] At least one reference link. 📖 for articles / specs, 🛠 for tools, 📹 for videos.
- [ ] Code example included if the item references specific markup. Use the
<!-- prettier-ignore-start -->pattern for HTML snippets Prettier would otherwise reflow. - [ ] Placed in the right section. Head items go under Head; CSS items go under CSS; cross-cutting items (security headers) go in Security, not Performance.
- [ ] Emoji-consistent bullets. Every follow-up bullet starts with 📖 / 🛠 / 📹.
Reasons to reject:
- Framework-specific (React-only, Vue-only). Belongs in a framework-specific guide.
- Build-tool-specific (Webpack flag, Vite plugin). Too narrow.
- Opinion-only without a verifiable check. "Use CSS Modules" is not a checklist item; "ensure CSS class-name uniqueness verifiable via
stylelint-no-duplicate-selectors" is. - Duplicate of an existing item with the same verification surface.
- Self-promotion disguised as an item. See #694.
- Outdated advice masquerading as new (e.g. adding
<meta http-equiv="X-UA-Compatible" content="IE=edge">in 2025+).
Reject template:
Per CONTRIBUTING.md ("No PR will be discarded without explanations"), always give a one-paragraph reason:
Thanks for the contribution! I'm closing this PR because <reason>.
Specifically:
- <concrete fact 1>
- <concrete fact 2>
If you want to take another run at this, <suggested-improvement>. Appreciate you
taking the time to propose this.
5.3 Quarterly link-rot sweep
git checkout main
git pull
lychee --config lychee.toml README.md
# Review lychee-out.md for new 404s, then fix in a single PR
git checkout -b link-rot-YYYY-QN
# ... fix links ...
pnpm format:fix
git commit -am "Link rot sweep YYYY-QN"
git push -u origin link-rot-YYYY-QN
# Open PR, merge
Tip
Run the sweep as a single PR per quarter rather than a flurry of one-PR-per-link. The reviewer overhead per PR is roughly constant; bundling reduces total review time by ~5x.
5.4 Add a new translation fork to the list
# After a translator opens an issue with their fork URL:
git checkout -b add-<language>-translation
# Edit README.md, insert the new row alphabetically:
# - 🇫🇮 Finnish: [username/Front-End-Checklist](https://github.com/username/Front-End-Checklist)
pnpm format:fix
git commit -am "Add <Language> translation fork"
git push -u origin add-<language>-translation
# Open PR, merge
5.5 Respond to a Code of Conduct report
Reports go to [email removed] (per CODE_OF_CONDUCT.md — Contributor Covenant v1.4). Per Covenant v1.4:
- Confirm receipt within 72 hours.
- Investigate without disclosing the reporter's identity.
- Take action proportional to severity: warning → temporary ban → permanent ban.
- Document the decision privately.
5.6 Rotate maintainer access
Single-maintainer repos have a succession risk. If the primary maintainer needs to hand off:
- Grant
admincollaborator access to the successor via Settings → Collaborators. - Transfer ownership (Settings → Transfer) or remain as co-owner.
- Update
authorfield inpackage.json. - Update contact in
CODE_OF_CONDUCT.md. - Announce in an Issue and on the README "Support" links.
5.7 Re-publish the priority badges
If the three SVG badges ever move or are regenerated:
- Commit the new SVGs to
data/images/priority/. - Update the three link-reference URLs at the bottom of
README.mdif the path changed. - Open a coordination issue listing all 13 translation forks and tagging their owners — they need to update their forks' link-reference URLs to match.
- Note the change in an issue that fork owners can link from their forks.
5.8 Tooling pipeline
developer edits README.md
↓
developer runs: pnpm format:fix
↓
prettier --write README.md (reflows according to .prettierrc)
↓
markdownlint README.md (reports violations, does NOT fix)
↓
git commit (Husky pre-commit hook may re-run format:check
if .husky/pre-commit is committed — currently it is not)
↓
PR opened
↓
CI runs: pnpm format:check (fails the PR if README.md is Prettier-dirty)
CI runs: lychee --config lychee.toml README.md (fails the PR on broken external links)
5.9 The absent tooling — notable gaps
The repo does not ship:
- A GitHub Actions workflow visible in the repo root (no
.github/workflows/*.ymltracked). Either the workflow lives in a private copy of the repo or the project relies on a third-party integration. - A
.husky/pre-commitor.husky/commit-msghook file. Thepreparescript installs Husky but no hook definitions are committed. - An
.github/ISSUE_TEMPLATE/directory. Issues are free-form, which contributes to the noise documented in §5.1. - A
.github/pull_request_template.md. PRs are unstructured. - A
SECURITY.md. The Code of Conduct lists[email removed]but there is no formal vulnerability-disclosure policy.
All of these are addressed in §8.5 Potential Improvements.
6. Performance
6.1 Repository performance
The repo is small (~5 MB) and simple. There are no performance concerns at the file-system or git level.
| Operation | Typical time |
|---|---|
git clone |
< 5 seconds on broadband |
pnpm install |
1-3 seconds (lockfile-resolved, ~80 packages cached) |
pnpm format:check |
< 1 second |
pnpm format:fix |
1-2 seconds (Prettier + markdownlint) |
lychee --config lychee.toml README.md (cached) |
5-10 seconds |
lychee --config lychee.toml README.md (cold cache) |
30-90 seconds (depends on external service latency) |
6.2 Document rendering performance
GitHub renders README.md in roughly 100-200 ms for a repo this size. The 850-line, ~29 KB README is far below GitHub's truncation threshold (5 MB), so the entire document renders inline. The ~310 external links resolve client-side as the user follows them — they do not affect render time.
The three priority badges (*.svg from raw.githubusercontent.com) load in parallel with the README HTML; corporate proxies that block raw.githubusercontent.com see broken-image icons, which is a UX issue, not a rendering issue.
6.3 Lychee link-checker performance
lychee.toml sets max_concurrency = 14, which fetches up to 14 URLs in parallel. With 310 external URLs and a 20-second timeout, a worst-case cold-cache run completes in roughly 310 / 14 * average_latency, which empirically is 30-90 seconds.
Tuning levers:
| Lever | Trade-off |
|---|---|
Increase max_concurrency |
Faster runs; risk of triggering rate-limiters and being blocked or 429'd |
Decrease max_concurrency |
Slower runs; less rate-limit pressure |
Increase max_cache_age |
Fewer external calls per CI run; later detection of newly broken links |
Decrease max_cache_age |
Faster detection of link rot; more bandwidth |
Add to exclude list |
Faster runs; missed link-rot detection on the excluded URL |
Tip
If CI runs become flaky, the most common culprit is rate-limiting on a few popular hostnames (Google, GitHub, MDN, W3C). Adding those hosts to the
excludelist trades coverage for stability — usually not worth it. Better to lowermax_concurrencyto 8 first and see if flakiness drops.
6.4 PR review throughput
The single-maintainer model creates a soft bottleneck. Empirically, the upstream merges roughly one PR per few weeks on small batches, longer for content-heavy PRs that need cross-checking. Quarterly link-rot sweeps (§5.3) are batched to amortize review cost.
Strategies to increase throughput are listed in §4.3 Editorial scaling and §8.5 Potential Improvements.
7. Security
A pure-content repo does not have a runtime attack surface, but it has editorial and supply-chain surfaces. This section is the threat model for the repo; for security advice on websites built using the checklist, see the User Guide → §5.5 Recipe: security review.
7.1 Threat model
| Threat | Vector | Mitigation |
|---|---|---|
| Malicious external link injected via PR | Contributor adds a - [ ] ![Low] Some tool: **My Link** pointing at a typosquat or phishing site |
Manual review of every external URL before merge; Lychee flags gross failures but not malicious-but-live links |
| Typosquat on a legitimate tool | Referenced URL drifts from original tool to a squatter | Quarterly link-rot sweep (§5.3); cross-check Wayback Machine for abrupt content changes |
| URL-shortener redirects to malicious content | Repo avoids shorteners except author's own ddias.link/* → X / Discord |
Policy: no third-party URL shorteners in PRs; reject or rewrite |
| Supply-chain compromise in devDependencies | Malicious release of prettier, markdownlint-cli, or husky |
Pin versions in pnpm-lock.yaml; review lockfile diff on dependency bumps; never run pnpm install on untrusted PR branches without inspection |
| Compromised contributor account pushes drive-by PR | Attacker with collaborator access force-pushes a malicious README | Only one admin; branch protection on main requiring PR review; 2FA on all collaborator accounts |
| Clickjacked OpenCollective donation flow | OC funding links at the bottom of README could be swapped | Review any PR that touches Backers / Sponsors / Support sections with extra care; the canonical URL is opencollective.com/front-end-checklist |
| XSS via README rendering | GitHub sanitizes README HTML; not a practical concern | Trust GitHub's Markdown sanitizer; do not import untrusted HTML |
| Trademark / copyright claim from a linked tool | External tool's terms change to prohibit linking | CC0 on our content does not protect us from their claims; remove the link if asked |
Warning
The biggest editorial security risk is a PR that adds a high-quality-looking item with a malicious link. A reviewer who skims fast will miss it. Always click through every new external URL on the first review pass, and run a
whoischeck if the domain is unfamiliar. Lychee will not catch this — it only checks that the URL responds, not that it responds with what you think it does.
7.2 Supply-chain — the live web app and the dev tooling
The repo itself does not run a web app, but it serves three priority SVGs and the README via raw.githubusercontent.com to anyone reading the file. Because GitHub's CDN is the host, the supply chain is GitHub's. Maintainers should:
- Trust GitHub's TLS and CDN integrity. Do not host badges on third-party CDNs without strong reason.
- Pin dev dependencies.
pnpm-lock.yamlis committed and pins exact transitive versions. - Review lockfile diffs on bumps. A 1-line
package.jsonchange can pull dozens of transitive dependencies; read the lockfile diff. - Avoid
pnpm install --no-frozen-lockfilein CI — it allows lockfile drift.
The three direct devDependencies and their licenses:
| Package | Version | License | Maintained by |
|---|---|---|---|
prettier |
3.3.3 | MIT | Prettier Foundation (well-resourced, multiple maintainers) |
markdownlint-cli |
0.42.0 | MIT | David Anson (long-time maintainer) |
husky |
9.1.6 | MIT | typicode (single primary maintainer) |
All MIT-licensed; no copyleft bleed-through.
7.3 Hosting and headers (the published artifact)
Because the "live app" is github.com, the repo benefits from GitHub's hosting security: HTTPS-only, HSTS preload, modern TLS ciphers, mature CDN. Maintainers cannot tune these — they get them for free.
If a maintainer wants to host a derivative on their own infrastructure (a fork served from a custom domain), they should run the security recipe in the User Guide → §5.5 against their own host: HSTS, CSP, X-Content-Type-Options, X-Frame-Options, HTTPS-only.
Caution
If a future iteration of the project ever ships a "tick the items in a hosted web app" experience (community forks already exist), that web app introduces a real runtime attack surface — XSS, CSRF, session hijacking, supply chain on its npm dependencies. Apply the User Guide's §5.5 security review checklist to it. The current repo does not ship such a web app.
7.4 License clarity (non-traditional security concern)
The license-field mismatch (§3.5) is technically a legal risk, not a security risk, but it shares the same "be cautious about your supply chain" mindset:
LICENSEfile: Creative Commons CC0 1.0 Universal (full legal text).package.jsonlicensefield:"CC-BY-4.0".- README's License section: links to CC0 1.0 Universal.
The LICENSE file is legally controlling. Most jurisdictions and conventions (SPDX, ChooseALicense, npm) treat the LICENSE file as authoritative when it differs from package.json. The repo's distribution is under CC0 1.0.
Warning
The
package.jsonfield should be corrected to"CC0-1.0". This is a one-line change but has real consequences: SPDX scanners, license-compliance tools, and corporate procurement systems readpackage.json'slicensefield and may reject the dependency on CC-BY-4.0 grounds. Until upstream fixes this, downstream consumers should document in their own README that they treat the work as CC0 1.0 per theLICENSEfile.
7.5 Reporting channels
| Channel | Use |
|---|---|
CODE_OF_CONDUCT.md contact ([email removed]) |
CoC violations; private security-adjacent concerns |
| GitHub Issues | Public bugs, broken links, content requests |
| X / Discord | Informal support; not a security channel |
7.6 Recommendations
- Add a
SECURITY.mdthat formalizes the email-disclosure channel. - Require 2FA on all collaborator accounts (GitHub repo or org setting).
- Enable branch protection on
mainwith required PR review even for maintainers. - Consider commit signing (Sigstore or traditional GPG) so consumers can verify provenance.
8. Developer Internals
8.1 The tooling stack — Prettier, markdownlint, Husky, Lychee, pnpm
Prettier 3.3.3 — the line-reflow gate. The single formatting enforcer for prose. With proseWrap: "preserve" it respects existing line breaks; with embeddedLanguageFormatting: "off" it leaves embedded HTML / JS / CSS in code blocks alone. The <!-- prettier-ignore-start --> / <!-- prettier-ignore-end --> guards appear ~20 times in README.md to suppress Prettier on inline HTML examples. Keep these guards when editing adjacent content — removing them triggers a large unintended reformat.
markdownlint 0.42.0 — the structure gate. With MD013, MD024, MD033 disabled (§3.3), it enforces:
- ATX-style headings (
#prefix, not underlines) - Exactly one H1 per document
- Blank lines around headings and fenced code blocks
- No trailing spaces on lines
- Consistent unordered-list marker (
-not*) - Code fences closed properly
- No bare URLs (must be wrapped in
<...>or Markdown link syntax)
A violation blocks pnpm format:fix from completing cleanly but does not auto-fix. Fix manually, rerun.
Husky 9.1.6 — the local commit gate. The prepare script (husky || true) runs on every pnpm install. At commit 09d56df, there is no .husky/ directory committed, which means hooks are not actively enforced locally unless a contributor independently configures them. Potential improvement: commit a .husky/pre-commit that runs pnpm format:check (see §8.5).
Lychee — the link-rot gate. Expected to run in CI using the committed lychee.toml. A maintainer invocation:
lychee --config lychee.toml README.md
Skipping cached URL https://developer.mozilla.org/en-US/docs/Web/HTML/Element/title
📝 Summary
---
🔍 Total links: 310
✅ Successful: 302
⏳ Timeouts: 0
🔀 Redirected: 0
👻 Excluded: 8
❓ Unknown: 0
🚫 Errors: 0
(Counts drift between runs as external sites change.)
pnpm — the package manager. pnpm-lock.yaml is committed and authoritative. npm install works but writes a competing package-lock.json; if you see both lockfiles in a contributor PR, ask them to rm package-lock.json and use pnpm instead.
8.2 Module reference
There are no source-code modules. The "modules" in the briefing-package sense are configuration files only — see §3 Configuration Reference for line-by-line documentation of each.
8.3 Code patterns and conventions
- Priority badges only from the three canonical SVGs. No custom tier colors. No per-section color overrides.
- Single H1, single Table of Contents. Never introduce a second H1 — markdownlint enforces this.
- "Back to top" links after every section end. Existing pattern:
**[⬆ back to top](#-table-of-contents)**. - Section separators are three dashes (
---). Consistent with existing usage. - Use task-list syntax (
- [ ]) for every check item. Not*and not prose paragraphs. - Two-space indent for continuation lines in long item rationales (matches
.editorconfig). - Fenced code blocks always have a language tag (
```html,```css,```js). - Code examples wrapped in
<!-- prettier-ignore-start -->/<!-- prettier-ignore-end -->when Prettier would otherwise reflow them in ways that hurt readability.
8.4 Testing strategy
The repo has no test suite in the JavaScript sense. The "tests" are:
| Test | What it catches |
|---|---|
pnpm format:check (Prettier) |
README is Prettier-dirty |
pnpm format:fix then markdownlint |
Structural lint violations |
lychee --config lychee.toml README.md |
Broken external links |
| Manual review per §5.2 rubric | Editorial quality |
A red CI on either format-check or Lychee blocks the PR. Reviewer judgment is the gate on rubric items.
Note
A "content unit test" might look like a script that asserts every checklist item has the expected three-part structure (label, badge, rationale). The repo does not currently ship one. A simple regex-based linter (
grep -E "^- \[ \] \*\*[^*]+:\*\* !\[" README.md | wc -lshould equal the total item count) would catch malformed items at PR time.
8.5 Potential improvements
Prioritized list of changes that would measurably improve the repo's quality and operations.
High priority:
- Resolve the license-field mismatch. Change
package.json"license"from"CC-BY-4.0"to"CC0-1.0". TheLICENSEfile is authoritative; alignpackage.jsonto match. One-line change, large downstream impact. - Commit a
.husky/pre-commithook that runspnpm format:checklocally to catch Prettier-dirty READMEs before push. - Add
.github/ISSUE_TEMPLATE/with forms for (a) broken link, (b) new-item proposal, (c) content bug, (d) translation notification. Would suppress the "Ui" / "Hi" / empty-issue noise documented in §5.1. - Add
.github/pull_request_template.mdwith the §5.2 review rubric as a contributor self-checklist. Self-review improves merge velocity. - Pin the priority SVG URLs to a commit SHA or GitHub Pages domain. Current URLs point to
refs/heads/main; a branch rename would break every inline badge across 13 translation forks.
Medium priority:
- Commit a GitHub Actions workflow running
pnpm format:checkandlychee --config lychee.toml README.mdon every PR. If one already exists in the author's private copy, move it into the repo. - Add
SECURITY.mdto formalize the[email removed]disclosure channel. - Audit and modernize jQuery- / Modernizr- / IE-conditional-comment-era items. Mark as "(legacy browsers only)" or move to a dedicated "Legacy" section at the end.
- Refresh deprecated tool links. Known rot examples: Twitter Card validator (now X's internal debugger), certain Google Webmaster Tools URLs (redirected to Search Console paths).
- Cross-link the Translations section to a bot-generated upstream-diff report so translators see what changed since their last sync.
- Add a
packageManagerfield topackage.json("packageManager": "pnpm@9.0.0") so Corepack resolves pnpm automatically for contributors. - Enable branch protection on
mainrequiring at least one approving review and green CI.
Low priority:
- Migrate CoC from Contributor Covenant v1.4 to v2.1. v2.1 has clearer enforcement guidelines and a broader definition of inappropriate behavior.
- Add an
enginesfield to pin Node LTS. - Publish a JSON sidecar (e.g.
checklist.json) alongsideREADME.mdas machine-readable data, making it easier for third-party apps to consume the checklist programmatically. - Add automated link-rot bot PRs (Dependabot-style) that open a PR each time Lychee catches a new 404.
- Add a "Last reviewed" timestamp at the top of each section so readers know when the content was last touched.
8.6 Contributing guide
The repo's CONTRIBUTING.md (not reproduced inline here — read it on GitHub) classifies contributions across QA, Marketing, Community, Code, and Money (sponsorship). For a new content item, the workflow is:
- Read
CONTRIBUTING.md. - Read this guide's §5.2 review rubric — pre-empt rejection.
- Fork; branch (
add-<item-name>); editREADME.md; insert your item in the topical right place. pnpm format:fix; commit; push.- Open a PR with a short description: what the item is, why it belongs, what tier and why, one concrete way to verify.
- Wait for CI to pass and the maintainer to review.
For a translation, follow §9.3.
For a derivative checklist, follow §9.4.
9. Integration Points
9.1 GitHub Issues and Pull Requests
The primary integration is GitHub itself. Issues, PRs, comment threads, and the rendered Markdown UI form the entire user experience.
| GitHub feature | Used for |
|---|---|
| Issues | Bug reports, broken-link reports, new-item proposals, translation notifications |
| Pull Requests | Content edits, link fixes, new items |
Task lists (- [ ]) |
Interactive checkboxes inside Issues and PRs |
Anchor links (#section-slug) |
Stable citations for code review |
| Markdown rendering | The whole product UI |
raw.githubusercontent.com |
Serving SVG badges |
9.2 OpenCollective
The repo's funding integration. The Backers and Sponsors sections render dynamic SVG banners pulled from opencollective.com/front-end-checklist/.... Contributors appear automatically once their PR merges. Do not accept PRs that manually edit these sections — they will be overwritten by the next OpenCollective sync.
| URL | Role |
|---|---|
opencollective.com/front-end-checklist |
Project funding page |
opencollective.com/front-end-checklist/backers/badge.svg |
Backers banner |
opencollective.com/front-end-checklist/sponsors/badge.svg |
Sponsors banner |
9.3 Translation forks
Translations live as independent forks, not in-repo translations. The upstream maintains only the list of fork URLs in the Translations section.
Why fork-based:
- Zero upstream burden — the upstream maintainer does not review translation quality or track drift.
- Translator ownership — the translator is the first-class maintainer of their translation, including future updates, PRs on their fork, and license decisions within CC0.
- Natural attribution — each fork's GitHub contribution graph credits the translator directly.
Trade-off: translations drift out of sync with the English upstream. A fork last updated in 2022 will be missing items added in 2024+. The upstream README makes no promise of synchronization.
Onboarding a new translation (when someone opens an issue titled "XYZ Translation"):
- Reply with the fork-instead-of-monorepo policy:
Thanks! We keep translations as independent forks. Fork the repo, translate README.md into your language, publish on your account, then reply here with the fork URL. I'll add it to the Translations section. - When the translator replies with a fork URL, open a PR adding the row to the Translations section (alphabetically by language name, with flag emoji).
- Merge.
- Close the original issue with a link to the merged PR.
Current fork list (13 translations as of 09d56df):
| Language | Fork |
|---|---|
| Japanese 🇯🇵 | miya0001/Front-End-Checklist |
| Spanish 🇪🇸 | eoasakura/Front-End-Checklist-ES |
| Chinese (Simplified) 🇨🇳 | JohnsenZhou/Front-End-Checklist |
| Korean 🇰🇷 | kesuskim/Front-End-Checklist |
| Portuguese 🇧🇷 | jcezarms/Front-End-Checklist |
| Vietnamese 🇻🇳 | euclid1990/Front-End-Checklist |
| Chinese (Traditional) 🇹🇼 | EngineLin/Front-End-Checklist |
| French 🇫🇷 | ynizon/Front-End-Checklist |
| Russian 🇷🇺 | ungear/Front-End-Checklist |
| Turkish 🇹🇷 | eraycetinay/Front-End-Checklist |
| German 🇩🇪 | xFuture603/Front-End-Checklist |
| Polish 🇵🇱 | mbiesiad/Front-End-Checklist |
| Indonesian 🇮🇩 | nniinnoo/Front-End-Checklist |
9.4 Sibling and derivative checklists
The same author maintains two companion checklists:
| Repo | Audience |
|---|---|
| thedaviddias/Front-End-Performance-Checklist | Performance-engineering depth: critical-path optimization, HTTP/2, CDN, caching headers, render-blocking analysis |
| thedaviddias/Front-End-Design-Checklist | Designer-developer handoff: typography, color systems, spacing, iconography, illustration |
Both siblings use almost identical file structure and tooling, confirming a "checklist playbook" you can derive against.
Derivative playbook for teams building a new thematic checklist (not a translation, not an internal subset):
- Fork the repo (or clone and push to a new repo — CC0 does not require fork lineage).
- Replace
README.mdcontent with your subject matter, preserving the structure: H1 with emoji, Table of Contents H2, "How to use?" H2 explaining your priority scheme and emoji legend, topical H2 sections with H3 subsections, items as- [ ] **Label:** ![Priority][priority_img] rationale., "Back to top" links after each section, Translations / Support / Contributors / Backers / Sponsors / License sections at the end. - Keep or swap the priority badges. Reuse the three SVGs in
data/images/priority/or design your own (any simple red/orange/green indicator works). - Keep the tooling.
.editorconfig,.prettierrc,.markdownlint.json,lychee.toml, and thepackage.jsonscripts all generalize unchanged. - Update
package.json: name, description, author, keywords. Remove or change thelicensefield to match your chosen license. - Refresh
CONTRIBUTING.md: adjust to reference your repo URL and any domain-specific contribution rules. - Adopt or replace
CODE_OF_CONDUCT.md: Contributor Covenant v1.4 (shipped here) is fine. Upgrade to v2.1 if desired. - Choose your license. CC0 is maximum freedom; CC-BY-4.0 requires attribution; MIT is code-friendly but an odd fit for prose. Put the exact license text in
LICENSEand reference it correctly inpackage.json. - Invite translation forks by example. Leave the Translations section in place; it signals that forks are welcome.
- Publish and promote.
9.5 External support channels
| Channel | URL | Role |
|---|---|---|
| Author profile | github.com/thedaviddias | Maintainer's GitHub presence |
| Author website | thedaviddias.com | Maintainer's homepage |
| X / Twitter | ddias.link/x | Public discussion |
| Discord | ddias.link/discord | Community chat |
| OpenCollective | opencollective.com/front-end-checklist | Funding |
9.6 Quick-reference command index
| Command | Purpose |
|---|---|
pnpm install |
Install devDependencies and Husky hooks |
pnpm format:check |
Fail if README.md is not Prettier-clean |
pnpm format:fix |
Prettier-write README.md, then markdownlint-check |
lychee --config lychee.toml README.md |
Check every external link |
grep -c "priority_img" README.md |
Count total checklist items |
grep -c "high_img" README.md |
Count High-priority items |
grep -c "medium_img" README.md |
Count Medium-priority items |
grep -c "low_img" README.md |
Count Low-priority items |
grep -nE "^## " README.md |
List all H2 sections |
grep -nE "^### " README.md |
List all H3 subsections |
9.7 Authoritative contacts
| Purpose | Contact |
|---|---|
| Code of Conduct enforcement | [email removed] |
| General support | X / Discord |
| Financial contribution | opencollective.com/front-end-checklist |
| Repository issues and PRs | github.com/thedaviddias/Front-End-Checklist/issues |
9.8 Counts at commit 09d56df
| Metric | Value |
|---|---|
| Tracked files | 15 |
| Source lines (non-Markdown) | 0 |
README.md lines |
~854 |
README.md size |
~29 KB |
| Top-level sections (H2) | ~20 |
| Subsections (H3) | ~24 |
| Checklist items | ~130 |
| External reference links | ~310 (per Lychee) |
| Priority SVG badges | 3 (low / medium / high) |
| Community translation forks | 13 |
| devDependencies | 3 (husky, markdownlint-cli, prettier) |
| Runtime dependencies | 0 |