The Skills Graph
1,863 atomic skills, cross-linked to 2,521 careers from our own career corpus and weighted by O*NET importance ratings where a matching occupation exists. The substrate for skill-gap analysis and the targeted free-course recommendations that follow.
What is in the skills graph
A node is a skill: an atomic competency that can be learned, practiced, and measured independently of other competencies at a meaningful level. There are 1,863 of these nodes today. An edge runs between a skill and a career, and it is tagged with the source that admitted it — a mention in the career's written profile, or an O*NET importance rating, in which case it also carries that score. Those are the only edges in the graph. Skill-to-skill relationships — prerequisites, substitutes, parent-and-child groupings — are not modelled; an earlier version of this page said they were, and no such edges exist in the published artifact.
Where the skill nodes come from
Our own skill catalogue. The nodes are ours. A skill exists in the graph because we wrote a profile for it, which is what lets the catalogue carry specific tools and methods at the granularity a learner actually searches — and which also means its coverage is editorial rather than exhaustive. A hand-maintained alias file normalizes the ways a skill gets written so that two spellings of the same competency do not become two nodes.
O*NET Content Model. The U.S. Department of Labor's occupational database rates 35 skill elements per occupation on importance and level, plus knowledge areas, abilities, and detailed work activities. O*NET is not where our skill nodes come from — it is where the numbers come from. Every weighted edge on this graph carries an O*NET importance score; every unweighted one does not, and the edge says which it is.
What we do not use. No job postings, no scraped or purchased hiring data, and no ESCO import. Until this revision this page described an ESCO subset import and a posting-ingestion pipeline that admitted new nodes above a calibrated frequency threshold and tagged them "emerging"; none of that was built. A new skill enters this graph when someone writes its profile, and not before.
How the skill–career edges are weighted
Same regime as the broader knowledge graph: an edge enters either because the career's profile names the skill, or because O*NET rates that skill at 3.0 or higher on its 1–5 importance scale for the matching occupation. Only the second kind carries a number. The source is tagged on every edge precisely so the two are never silently averaged into a single misleading score — an unweighted mention and a survey-backed 4.2 are different claims and the graph keeps them apart.
What skill-gap analysis actually does
A skill-gap analysis answers the question: between where I am and the skills a career asks for, what should I learn next? It is worth being exact about what it compares, because the honest answer is simpler than the phrase suggests — and because it does not read the graph described above.
- What you have. The skills you have marked complete — ticked off in a career roadmap and saved against your account. There is no test-derived proficiency level here and no credential import: a skill is either marked done or it is not.
- What the career asks for. A short ordered skill chain written by hand for that career — a deliberate learning order, not a statistical profile of incumbents. On the level-to-level learning path the target is instead the skill mix we describe for the higher level, which does carry a percentage per skill.
- What comes out. Coverage — how much of the chain you already have — plus the remaining steps in chain order, or, on the level path, sorted by the largest percentage distance. Time estimates come from a small hand-maintained hours-per-skill table, and any skill outside it falls back to a flat default. Treat those hours as a planning sketch, not a measurement.
Two things follow, and both are worth saying plainly. The gap is a coverage check, not a proficiency comparison: it can tell you that SQL is missing from your list, never that your SQL is weak. And the skills graph on this page is a separate artifact feeding separate pages — until this revision, this section described the gap as a weighted comparison against a median-incumbent profile drawn from the graph. No such comparison exists in the product.
How course recommendation closes the loop
For each remaining skill we surface learning resources from two places. The first is a small hand-picked map of canonical free sources — MDN, the official language and framework documentation, freeCodeCamp, javascript.info and their equivalents — attached directly to the skill name. The second is a course table in our database, where each row is mapped to the skills and careers it covers. On a career roadmap those rows come out grouped by the level they belong to and then in a position we set by hand; the mapping also carries a relevance score, which is what our partner API sorts on. That is the whole of the ranking. No scoring model sits behind it weighing instructor credentials, syllabus completeness or learner-reported outcomes; earlier versions of this page said one did.
The link-health sweep is currently switched off. A job exists that checks every course URL and flags the dead ones, and when it ran it ran daily, never monthly as this page used to claim. It has been paused since 4 July 2026 while the courses feature is rebuilt, and it is gated twice over so that it cannot restart by accident. Until it is back on, assume some course links have rotted since they were added.
We take no affiliate or referral revenue from course providers — there is no such arrangement and no tracking parameter behind these links. The Future of Jobs Report (WEF, 2023) and McKinsey's education-to-employment work (Mourshed et al., 2012) both document mis-aligned course recommendation as a primary cause of skill-program waste; introducing a financial conflict here would only add to that pile.
Refresh cadence and provenance
The graph is a build artifact, not a live service, so it has no schedule of its own. It is regenerated when we regenerate it — after new skill profiles are written, after a threshold changes, or after a new upstream release lands — and the run stamps the artifact with its build date, the thresholds in force and a hash of every input file, so any published figure can be traced back to the exact inputs that produced it. What follows is what each input is actually pinned to.
- Skill and career nodes: whenever a profile is written or revised. Editorial, not scheduled.
- O*NET importance ratings: pinned to O*NET 29.0 (2024). They move when we take a new O*NET release, which is annual.
- Course rows: maintained by hand in the database. The automated link check that used to guard them is paused — see the section above.
There is no ESCO feed, no posting-evidence window and no expert-review tier on any of these, which is what this list claimed until this revision.
Honest limitations
The graph reflects what we wrote and what O*NET rates — not what employers are currently asking for. We hold no demand signal of any kind: no postings, no hiring data, nothing that would tell you a skill got hot this quarter. So a skill list here is a description of a role as it is documented, not a read on this month's market. A skill-gap analysis is a reasonable plan for what to learn, not a claim that learning it will land the job.
The mention layer inherits the noise of text matching. An edge that exists because a profile named a skill is only as good as the name-matching behind it: a broadly-worded skill can attach itself to far more careers than it belongs to, and a skill nobody happened to write down is simply absent. A hand-maintained alias file and a commodity-skill threshold blunt this; neither removes it. Where O*NET rates the occupation, the score on the edge is the part worth trusting.
Course links are only as fresh as the last sweep, and the sweep is off. Rows are added and edited by hand, and the automated link check has been paused since July 2026. Expect some dead links until it is turned back on.
It describes U.S. occupational structure. O*NET is a U.S. dataset and it is the only occupational authority weighting this graph. There is no European crosswalk — until this revision this section claimed non-English markets fell back to ESCO, which would require an ESCO import we have never done. A reader outside the United States is reading a U.S. structure, and no snapshot stamp on any career page says otherwise.
Citations
- U.S. Department of Labor / Employment and Training Administration (2024). O*NET Content Model — Skills, Knowledge, Abilities. https://www.onetcenter.org/content.html link
- World Economic Forum (2023). Future of Jobs Report 2023. World Economic Forum, Geneva. link
- Mourshed, M., Farrell, D., & Barton, D. (2012). Education to employment: Designing a system that works. McKinsey Center for Government. link
From our own skill catalogue — the 1,863 skills that have a written profile on this site. That catalogue is editorial: a skill exists as a node because we wrote it, which is why it reaches finer-grained tooling ("Postgres", "prompt engineering") than a national taxonomy updated on a multi-year cycle. O*NET is not the source of the nodes; it is the source of the importance scores that weight the links between those nodes and careers, and it covers 35 rated skill elements per occupation. We do not import ESCO and we do not derive skills from job postings — an earlier version of this page claimed both.
A skill is treated as atomic when it can be learned, practiced, and measured independently of others at a meaningful level. "Python" is atomic. "Backend engineering" is not — it is a cluster of atomic skills (Python, SQL, system design, Linux, observability). We err toward atomicity because course recommendation, skill-gap analysis, and credential mapping all work better at the atomic level. Clusters are computed from atomic skills, never the reverse.
Through the same two paths that govern the broader knowledge graph, and each link is tagged with which one admitted it. Either the skill is named in that career's written profile — in which case the link carries no score, because a mention is not a measurement — or O*NET rates it at 3.0 or higher for the matching occupation, in which case the link carries that rating. A consequence worth stating: every O*NET-derived weight you will see falls between 3.0 and 5.0, because 3.0 is the admission floor and 5 is the top of O*NET's scale. A low number there does not mean a weak link; it means the link only just cleared the floor.
When a user completes a skills assessment or self-rates against a career's skill requirements, the gap between current skill level and required skill level is computed per atomic skill. The largest gaps are surfaced as "skills to close." For each gap, we recommend the highest-rated free or low-cost course we can verify, drawn from a vetted catalogue of open-courseware sources (MIT OCW, Stanford Online, Coursera open courses, edX archived offerings, freeCodeCamp, official documentation). We do not earn affiliate revenue from course providers — recommendations are sorted by independent quality signals, not by referral commissions.
Two reasons. First, auditability: a curated graph lets us trace any skill–career link back to a specific evidence source, which an LLM extraction does not. Second, latency and cost: serving 2,521 career pages against a live LLM extraction at request time is expensive and slow; precomputing the graph keeps pages fast and free for the user. To be exact about what does the normalizing: there is no model in this loop at all. Aliases for each skill are derived by rule — the full name, the name with parentheticals and trailing noise stripped, separator splits, two-word n-grams and distinctive single tokens — and then corrected by a hand-maintained alias file with per-skill add and drop lists plus a global drop list. Until this revision this answer claimed LLM-assisted normalization and a review step before edges are published; the build has neither.
Editorially, and that is the honest answer rather than a flattering one. A new skill enters because someone writes its profile and names it in the careers it belongs to; it then links to those careers through the corpus path, unweighted, because O*NET has not rated it and may not for years. There is no automated pipeline that detects a rising skill from market data, no auto-admission threshold, and no decay mechanism that retires a fading skill — earlier versions of this page described all three, and none was built. The practical limit: the graph is as current as our writing, and no more current than that.
Yes, in two ways we disclose. First, the graph reflects a mixture of what we wrote and what O*NET measured, and those are not the same kind of claim. Where a link came from our corpus it inherits our editorial judgement and the noise of text matching — a broadly-worded skill can attach to far more careers than it belongs to, and a skill nobody thought to name in a profile is simply missing. Only the O*NET-scored links rest on survey data. Second, course quality on the open web is highly variable. We curate the source list, but a recommended course can still be outdated or weakly aligned with the target skill. We invite users to flag recommendations that are not useful so the catalogue improves.