Skip to content

Contributing

Thanks for helping keep this roadmap useful. This is a curated list, not an exhaustive one — every entry should be something you would genuinely recommend to someone learning frontend.

What belongs here

  • Free or freemium — the core value must be usable without paying.
  • Actively maintained — the site works, the content is not years out of date.
  • In English, or clearly labeled otherwise with a language tag, e.g. - [Learn JS](https://learn.javascript.ru/) — Modern JavaScript tutorial. [ru].
  • Focused — one tool, tutorial, reference, game, or cheatsheet per entry.

What does not

  • Paid-only courses, or content behind a paywall after a teaser.
  • Link-farm and SEO blogs that just aggregate other people’s articles.
  • Unmaintained tools, dead projects, sites with expired certificates.
  • Anything that requires signup, login, or an email address to view.
  • Duplicates of a resource already listed under another name.

Entry format

The format is defined in one place — docs/STYLE.md. Read it before you open a PR. Every entry is a single-line list item:

- [Title](https://example.com/) — Description of what it is.

Real examples from docs/CSS.md:

- [CSS Reference #1](https://cssreference.io/) — List of all CSS properties.
- [Flexbox Froggy](https://flexboxfroggy.com/) — Game for learning CSS flexbox.
- [Clippy](https://bennettfeely.com/clippy/) — CSS clip-path maker.

The three things people get wrong most often:

  1. The separator is , an em dash with a space either side. Not a hyphen, not an en dash, not a colon.
  2. The description starts with a capital letter and ends with a full stop. Entries used to end with a semicolon; they no longer do. Opening with a numeral (3KB alternative…), a quotation mark, or a literal lowercase identifier (tsconfig.json options…) is fine — the rule is that it must not open with an ordinary lowercase word.
  3. Tags come after the full stop, and only from the closed vocabulary in the style guide: [freemium] [paid], [beginner] [intermediate] [advanced], [ru] [uz]. Free and English are the defaults and are never tagged. If you are not sure a tag applies, leave it off.

Where to add it

  • Pick the file that matches the topic. They are listed here in the same groups, and the same order, as the Contents table in README.md — if you change one, change the other:

    • Foundationsdocs/HTML.md, docs/CSS.md, docs/JAVASCRIPT.md
    • Language & typesdocs/TYPESCRIPT.md
    • Frameworksdocs/REACTJS.md, docs/FRAMEWORKS.md
    • Craftdocs/ACCESSIBILITY.md, docs/PERFORMANCE.md, docs/SECURITY.md, docs/TESTING.md, docs/BROWSER-APIS.md
    • Toolingdocs/GIT.md, docs/TOOLING.md, docs/DEPLOYMENT.md
    • Design & UIdocs/DESIGN.md, docs/UI-FRAMEWORKS.md
    • Beyond codedocs/LEARNING.md, docs/AI-TOOLS.md, docs/PRACTICE.md

    docs/STYLE.md and docs/TRANSLATIONS.md are the only other files in docs/. They describe how the repo is written rather than listing resources, so nothing gets added to them.

  • Pick the section inside it. The section names are fixed: ## Learn for tutorials, courses, and videos; ## Reference for documentation, cheatsheets, and galleries; ## Practice for games, exercises, and templates; ## Tools for generators, converters, and libraries; ## Deep dives for focused long-form reading.

  • Append to the end of the section. The lists are not alphabetical, and reordering them makes diffs unreadable.

Proposing a new section or file

Open an issue first so we can agree on the shape before you write it. The five ## section names are fixed, so what you are usually proposing is a ### subgroup inside one of them — most often inside ## Reference or ## Tools, which are the sections that grow long enough to need breaking up. A subgroup needs three or more entries to be worth having, in a section of roughly a dozen entries or more. Otherwise put them in the closest existing section.

A whole new docs/*.md file needs two more things, both of them one line:

  1. A row in the Contents table in README.md, under the group it belongs to — Foundations, Language & types, Frameworks, Craft, Tooling, Design & UI, or Beyond code.
  2. An entry in site/src/lib/repo.mjs, in the matching sidebar group, so the page exists on the website — see The website below.

Nothing else needs touching: topic files are English only, so a new one never involves a translated file — see docs/TRANSLATIONS.md.

The website

The Markdown files are the source of truth. The site at https://shuhrat-kobulov.github.io/frontend-roadmap/ is generated from them by the Astro project in site/, which reads README.md, ROADMAP.md, everything in docs/, and the other Markdown at the repo root where they already are — there is no second copy of any file.

You never need to touch site/. Edit the Markdown, open your PR, and the page updates itself when it merges. site/ only changes if you are changing how the site is built, and a new docs/*.md file needs one line adding to site/src/lib/repo.mjs so it appears in the sidebar.

To preview the site locally: cd site && npm install && npm run dev.

Open a broken link issue. Include the file, the URL, and what you see when you visit it — a 404, a parked domain, and a paywall each get handled differently. A suggested replacement is welcome but not required. Please don’t open a PR that only deletes a link without saying what happened to it.

Pull request checklist

  • I opened the link in a fresh browser session and it loads.
  • It is free to use and needs no signup.
  • The line matches docs/STYLE.md: em dash, capitalized description, full stop, tags only from the fixed vocabulary.
  • One resource per line, appended to the end of the right section.
  • I searched the repo and this resource is not already listed.
  • I did not reorder or reformat any unrelated lines.

Small PRs get merged fast. A PR that adds one good link is better than a PR that adds ten unsorted ones.

By contributing you agree that your contribution is licensed under CC BY 4.0, and that you will follow the Code of Conduct.