pub-dev
Skill0 starsChanged 9 months agoMITView on GitHub
Use when finding Dart or Flutter packages, checking pub scores, comparing versions, or reading package docs. Provides API and navigation flows for pub.dev.
In this repository6 other files it gives its agents.
- caniuseSkill
- crates-ioSkill
- news-ycombinatorSkill
- mdn-web-docsSkill
- pypiSkill
- web-browsingSkill
The file
We split this skill into the rules it gives an agent
10 rules. About 0 are common, 2 are distinctive, and 8 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
8
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 21
Search (returns names only): GET https://pub.dev/api/search?q={query}&page=1
- Distinctive: line 31
Use selectors and Navigation Flows below
- Distinctive: line 35
Default to Programmatic: if you know the package name — one call returns everything including all versions and full pubspec
- Very specific: line 383
Read latest.pubspec.environment.sdk — check if the Dart SDK constraint is compatible with the user's Dart version
- Very specific: line 384
Read latest.pubspec.dependencies — mention any notable transitive dependencies
- Very specific: line 396
Prefer packages with shorter dependency lists and recent latest.published
- Very specific: line 417
Check: advisories[].length > 0 — warn if unpatched CVEs exist for current version
- Very specific: line 418
Check versions.length — more versions = more maintained history
- Very specific: line 426
Server-rendered MPA: All pages are fully server-rendered HTML.
- Very specific: line 469
Docs links only appear for versions that have documentation: Not every version in the versions list has a docs link (a[title="Go to the …
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
pub.dev — Dart & Flutter Package Registry
Overview
Covers the full read workflow on pub.dev: searching for packages, reading package detail pages (readme, changelog, install instructions), browsing version history, and retrieving metadata via the JSON API. The JSON API is the recommended path for automation — returns full pubspec.yaml data including dependencies, SDK constraints, and topics.
Not covered here: Publishing packages, managing publishers, account settings, admin actions.
Auth required for: Publishing, liking packages, managing publishers. All browsing and search are public.
Agent Paths
Programmatic [API] — No browser needed
- Search (returns names only):
GET https://pub.dev/api/search?q={query}&page=1 - Package metadata + all versions:
GET https://pub.dev/api/packages/{name} - Score, likes, downloads:
GET https://pub.dev/api/packages/{name}/score - Security advisories:
GET https://pub.dev/api/packages/{name}/advisories - Publisher info:
GET https://pub.dev/api/packages/{name}/publisher - Download archive:
GET https://pub.dev/api/archives/{name}-{version}.tar.gz
Required headers: None — all public endpoints are open
Browser [Browser] — Requires browser control
- Use selectors and Navigation Flows below
- Required when: reading the rendered readme, browsing the changelog, viewing install instructions with copy-paste commands, or interacting with a logged-in account
When to use which
- Default to Programmatic if you know the package name — one call returns everything including all versions and full pubspec
- Use Browser when: the task involves reading formatted readme content, or the user wants to copy the pubspec.yaml dependency line from the UI
- Avoid
/packages?q=browser search — robots.txt disallows it for bots; useGET /api/search?q=instead
Agent Knowledge Note
Most frontier LLMs have pub.dev structure in training data. This skill adds value via:
- Search API returns names only —
GET /api/search?q={query}returns{packages: [{package: "name"}]}, not descriptions. You need a secondGET /api/packages/{name}call to get the description, version, or any metadata. This surprises agents expecting a rich search response like PyPI's. versions[]is oldest-first — theversionsarray in the package API response lists from oldest to newest. Use the top-levellatestobject for current version data, notversions[-1]. Agents commonly get this wrong.+in version numbers — Dart uses+for build metadata (e.g.,0.12.0+4). In browser URLs this stays as+(/packages/http/versions/0.12.0+4), but in archive URLs it's percent-encoded (http-0.12.0%2B4.tar.gz). The API response provides both the correctversionstring and the correctly-encodedarchive_url.- No Dart SDK version in a dedicated field — the minimum Dart SDK version is nested at
latest.pubspec.environment.sdk(a constraint string like"^3.4.0"), not a top-level field. - Popularity data IS available via API —
GET /api/packages/{name}/scorereturnsgrantedPoints,maxPoints,likeCount,downloadCount30Days, and a fulltags[]array. Don't rely on the browser/scoretab — use the API endpoint. - Security advisories ARE available via API —
GET /api/packages/{name}/advisoriesreturns the full OSV-format advisory list with GHSA IDs, CVEs, severity, and affected version ranges. - robots.txt disallows browser search URL —
/packages?q=is disallowed. The API search endpoint/api/search?q=is not disallowed and is the correct path.
Site Map
| Page | URL Pattern | Notes |
| Homepage | https://pub.dev/ | Search form, trending/new packages |
| Browser search | https://pub.dev/packages?q={query} | Disallowed by robots.txt — use API instead |
| Package readme | https://pub.dev/packages/{name} | Default tab — readme content |
| Package changelog | https://pub.dev/packages/{name}/changelog | Version history prose |
| Package install | https://pub.dev/packages/{name}/install | pubspec.yaml snippet + flutter/dart commands |
| Package versions | https://pub.dev/packages/{name}/versions | All versions with download links |
| Package example | https://pub.dev/packages/{name}/example | Example code tab |
| Package score | https://pub.dev/packages/{name}/score | pub points breakdown |
| Publisher | https://pub.dev/publishers/{domain} | e.g. /publishers/dart.dev |
| JSON API (package) | https://pub.dev/api/packages/{name} | Full metadata + all versions |
| JSON API (search) | https://pub.dev/api/search?q={query}&page=1 | Returns names only |
| Archive download | https://pub.dev/api/archives/{name}-{version}.tar.gz | Direct package download |
Page Structures
Homepage
| Element | Selector | Notes |
| Search form | form.search-bar | Wraps the search input |
| Search input | input[name="q"] | Also: input[type="search"], input[title="Search"] |
| Sign in | #-account-login | Google OAuth |
| Package name links (listings) | a.mini-list-item-title | 22 matches on homepage — package cards |
| Publisher links (listings) | a.publisher-link | 20 matches — publisher names on package cards |
| View All Flutter packages | a[href^="/packages?q=sdk%3Aflutter"] | "VIEW ALL" link |
| View All Dart packages | a[href^="/packages?q=sdk%3Adart"] | "VIEW ALL" link |
| View All trending | a[href^="/packages?sort=trending"] | "VIEW ALL" link |
Package Detail (/packages/{name})
| Element | Selector | Notes |
| Tab navigation | ul.detail-tabs-header | Contains all 5 tab links |
| Tab: Readme | a[href="/packages/{name}"] | Default tab |
| Tab: Changelog | a[href="/packages/{name}/changelog"] | |
| Tab: Installing | a[href="/packages/{name}/install"] | pubspec.yaml snippet |
| Tab: Versions | a[href="/packages/{name}/versions"] | |
| Tab: Example | a[href="/packages/{name}/example"] | May be absent if no example |
| Active tab content | section.tab-content | Also: section.tab-content.detail-tab-readme-content on readme tab |
| Metadata sidebar | aside.detail-info-box | Publisher, score, platforms, topics, dependencies |
| Like button | button[title="Like this package"] | Requires login to function |
| Dart SDK badge | a[href^="/packages?q=sdk%3Adart"] | Shown if Dart-compatible |
| Flutter SDK badge | a[href^="/packages?q=sdk%3Aflutter"] | Shown if Flutter-compatible |
| Platform badges | a[href^="/packages?q=platform%3Aandroid"] etc. | Android, iOS, Linux, macOS, Web, Windows |
| Topic tags | a.topics-tag | Multiple matches — each links to topic search |
| Publisher link | a[href^="/publishers/"] | In sidebar — 3 matches (sidebar repeats) |
Versions Page (/packages/{name}/versions)
| Element | Selector | Notes |
| Versions tab content | section.tab-content.detail-tab-versions-content | Wraps full version list |
| Version page link | a[title="Visit {name} {version} page"] | e.g. "Visit http 1.6.0 page" |
| Version archive download | a[title="Download {name} {version} archive"] | Direct .tar.gz link |
| Version docs link | a[title="Go to the documentation of {name} {version}"] | Not all versions have docs |
| Atom feed | a[href^="/api/packages"] | Versions feed link |
Navigation Flows
Flow: Search for a Package [API] (Recommended)
Starting point: None — direct HTTP fetch Prerequisites: None
| Step | Action | Target | Notes |
| 1 | fetch | https://pub.dev/api/search?q={query}&page=1 | Returns package names only |
| 2 | read | packages[].package | Array of name strings |
| 3 | fetch | https://pub.dev/api/packages/{packages[0].package} | Get full metadata for top result |
Success state: JSON with name, latest.version, latest.pubspec.description.
Branching:
- If
packages[]is empty → no results; try broader search term - If
nextfield present → paginate:GET https://pub.dev/api/search?q={query}&page=2
Flow: Search via Browser [Browser]
Starting point: https://pub.dev/
Prerequisites: None
| Step | Action | Target | Value | Wait For | Timeout |
| 1 | navigate | — | https://pub.dev/ | input[name="q"] visible | 5s |
| 2 | type | input[name="q"] | Search term | — | — |
| 3 | press | input[name="q"] | Enter | URL contains /packages?q= | 3s |
| 4 | read | a.mini-list-item-title | — | Package results visible | — |
Success state: URL is https://pub.dev/packages?q={term} with a.mini-list-item-title result links visible.
Flow: View Package Detail [Browser]
Starting point: Any page or direct URL Prerequisites: None
| Step | Action | Target | Value | Wait For | Timeout |
| 1 | navigate | — | https://pub.dev/packages/{name} | section.tab-content visible | 5s |
| 2 | read | section.tab-content, aside.detail-info-box, ul.detail-tabs-header | — | Content loaded | — |
Success state: Package page with readme content in section.tab-content, metadata sidebar in aside.detail-info-box, and tab navigation in ul.detail-tabs-header.
Flow: Browse Package Tabs [Browser]
Starting point: https://pub.dev/packages/{name}
Prerequisites: None
| Step | Action | Target | Wait For | Timeout |
| 1 | click | a[href="/packages/{name}/changelog"] | New page loads | 3s |
| 2 | read | section.tab-content | — | — |
Tab URLs (navigate directly instead of clicking):
| Tab | URL |
| Readme | https://pub.dev/packages/{name} |
| Changelog | https://pub.dev/packages/{name}/changelog |
| Installing | https://pub.dev/packages/{name}/install |
| Versions | https://pub.dev/packages/{name}/versions |
| Example | https://pub.dev/packages/{name}/example |
Note: Tab clicks navigate to new URLs — this is not a JavaScript tab toggle. Content is server-rendered on each URL.
Flow: Get Package Metadata [API] (Recommended)
Starting point: None — direct HTTP fetch Prerequisites: None
| Step | Action | Target | Notes |
| 1 | fetch | https://pub.dev/api/packages/{name} | No auth, no rate limit |
| 2 | read | latest.version, latest.pubspec.description, latest.pubspec.environment.sdk | Core fields |
Success state: JSON with top-level keys name, latest, versions.
API Response Shapes
GET /api/packages/{name}
{
"name": "http",
"latest": {
"version": "1.6.0",
"pubspec": {
"name": "http",
"version": "1.6.0",
"description": "A composable, multi-platform, Future-based API for HTTP requests.",
"repository": "https://github.com/dart-lang/http/tree/master/pkgs/http",
"topics": ["http", "network", "protocols"],
"environment": {
"sdk": "^3.4.0"
},
"dependencies": {
"async": "^2.5.0",
"http_parser": "^4.0.0",
"meta": "^1.3.0",
"web": ">=0.5.0 <2.0.0"
},
"dev_dependencies": {
"test": "^1.21.2"
}
},
"archive_url": "https://pub.dev/api/archives/http-1.6.0.tar.gz",
"archive_sha256": "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412",
"published": "2025-11-10T18:27:56.434747Z"
},
"versions": [
{
"version": "0.2.7+0",
"pubspec": { "name": "http", "version": "0.2.7+0", "description": "..." },
"archive_url": "https://pub.dev/api/archives/http-0.2.7%2B0.tar.gz",
"archive_sha256": "cc4fedb...",
"published": "2012-11-30T20:40:39.500320Z"
}
]
}Key fields:
| Field | Description |
latest.version | Current stable version string |
latest.pubspec.description | One-line package description |
latest.pubspec.environment.sdk | Dart SDK constraint (e.g. "^3.4.0") |
latest.pubspec.dependencies | Object: dep name → version constraint |
latest.pubspec.topics[] | Topic tags (e.g. ["http", "network"]) |
latest.pubspec.repository | Source repository URL |
latest.published | ISO 8601 publish timestamp |
latest.archive_url | Direct download URL for the .tar.gz |
versions[] | Oldest first — full list; use latest for current |
versions[].version | Version string (may contain + for build metadata) |
versions[].archive_url | Download URL with + encoded as %2B |
GET /api/search?q={query}&page=1
{
"packages": [
{ "package": "http" },
{ "package": "dio" },
{ "package": "chopper" }
],
"next": "https://pub.dev/api/search?q=http&page=2"
}Note: Returns package names only. No description, version, or score. Call GET /api/packages/{name} for each result to get metadata.
GET /api/packages/{name}/score
{
"grantedPoints": 160,
"maxPoints": 160,
"likeCount": 8408,
"downloadCount30Days": 8609458,
"tags": [
"publisher:dart.dev",
"sdk:dart",
"sdk:flutter",
"platform:android",
"platform:ios",
"platform:linux",
"platform:macos",
"platform:web",
"platform:windows",
"is:null-safe",
"is:dart3-compatible",
"license:bsd-3-clause",
"topic:http"
]
}Key fields:
| Field | Description |
grantedPoints | pub points earned (0–160) |
maxPoints | Maximum possible points (160) |
likeCount | Total likes |
downloadCount30Days | Downloads in the last 30 days |
tags[] | Derived tags: publisher, SDK support, platforms, licenses, topics |
GET /api/packages/{name}/advisories
{
"advisories": [
{
"id": "GHSA-4rgh-jx4f-qfcq",
"aliases": ["CVE-2020-35669"],
"summary": "http before 0.13.3 vulnerable to header injection",
"severity": [{ "type": "CVSS_V3", "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N" }],
"database_specific": {
"severity": "MODERATE",
"github_reviewed": true,
"cwe_ids": ["CWE-74"]
},
"affected": [{
"ranges": [{ "events": [{ "introduced": "0" }, { "fixed": "0.13.3" }] }]
}]
}
],
"advisoriesUpdated": "2024-04-28T09:27:57.869544Z"
}Key fields:
| Field | Description |
advisories[] | Array of OSV-format security advisories (empty array = no known CVEs) |
advisories[].id | GHSA identifier |
advisories[].aliases[] | CVE numbers |
advisories[].summary | One-line description |
advisories[].database_specific.severity | CRITICAL / HIGH / MODERATE / LOW |
advisories[].affected[].ranges[].events | introduced and fixed version bounds |
advisoriesUpdated | Timestamp of last advisory sync |
GET /api/packages/{name}/publisher
{ "publisherId": "dart.dev" }Returns just the publisher domain string. Empty publisherId means no verified publisher. Matches publisher:dart.dev tag in /score response.
Common Agent Tasks
"Add {package} to my project" / "What's the pubspec.yaml line for {package}?"
- Fetch:
GET https://pub.dev/api/packages/{name} - Read
latest.version - Output the pubspec.yaml dependency line:
dependencies: {name}: ^{latest.version} - Read
latest.pubspec.environment.sdk— check if the Dart SDK constraint is compatible with the user's Dart version - Read
latest.pubspec.dependencies— mention any notable transitive dependencies
Output: The pubspec.yaml snippet + Dart SDK requirement
"Find a package that does X"
- Fetch:
GET https://pub.dev/api/search?q={X}&page=1 - Get top 3-5 package names from
packages[].package - Fetch all in parallel:
GET https://pub.dev/api/packages/{name}for each - Compare:
latest.pubspec.description,latest.pubspec.topics[],latest.pubspec.environment.sdk - Prefer packages with shorter dependency lists and recent
latest.published
Output: Comparison table of name / description / Dart SDK req / dep count / last published
"Compare {pkg1} vs {pkg2}"
- Fetch all in parallel (4 calls total):
GET /api/packages/{pkg1}andGET /api/packages/{pkg2}— metadataGET /api/packages/{pkg1}/scoreandGET /api/packages/{pkg2}/score— popularity + pub points
- Optionally also fetch in parallel:
GET /api/packages/{pkg1}/advisoriesandGET /api/packages/{pkg2}/advisories— security
- Compare from
latest+ score:latest.version— current stable versionlatest.published— recencylatest.pubspec.environment.sdk— Dart SDK requirementlatest.pubspec.dependencies— count of runtime dependenciesgrantedPoints/maxPoints— pub points (code quality, docs, platform support)downloadCount30Days— actual usage (most important popularity signal)likeCount— community endorsement
- Check:
advisories[].length > 0— warn if unpatched CVEs exist for current version - Check
versions.length— more versions = more maintained history
Output: Side-by-side table of both packages including downloads, pub points, and advisory status
Dynamic Content Patterns
- Server-rendered MPA: All pages are fully server-rendered HTML. Use
domcontentloaded— no JS wait needed for content. - Tab clicks navigate to new URLs: Each tab (
/changelog,/install,/versions,/example) is a separate page load, not a JavaScript toggle. Always wait fordomcontentloadedafter clicking a tab. - Version list is fully rendered: The
/versionspage lists all versions in the HTML — no pagination, no lazy loading.section.tab-content.detail-tab-versions-contentcontains the full list. - Readme is rendered Markdown: The readme tab content is server-rendered HTML from Markdown. Read
section.tab-contentfor the full formatted content.
Timing & Waiting
| Transition | Wait For | Typical Delay |
| Page navigation | domcontentloaded | 0.5–2s |
| Tab click (changelog, install, etc.) | domcontentloaded | 0.5–2s |
| Search submit | URL changes to /packages?q= | 1–2s |
| JSON API fetch | Response body | 0.2–1s |
Rate Limits
| Scope | Limit | Notes |
| JSON API | No documented limit | Very permissive; CDN-backed |
| Browser | robots.txt disallows /packages?q= | Use API search instead |
Parallel requests: Safe to fire multiple API requests in parallel — commonly needed to enrich search results (fetch metadata for each of N names returned by the search API).
Common Gotchas
- Search API returns names only.
GET /api/search?q={query}returns{packages: [{package: "name"}]}. There is no description, version, or score in this response. You must callGET /api/packages/{name}separately for each result to get metadata. versions[]is oldest-first. The array starts at the very first release (often from 2012–2014 for popular packages) and ends at the latest. Use the top-levellatestobject for current version data.+in version numbers is URL-encoded in archive paths. Version0.12.0+4appears as+in the browser URL (/packages/http/versions/0.12.0+4) but as%2Bin the archive URL (http-0.12.0%2B4.tar.gz). The API provides the correctly-encodedarchive_url— use that directly rather than constructing the URL yourself.- No Dart SDK field at the top level. Minimum Dart SDK is at
latest.pubspec.environment.sdk, nested inside the pubspec object. There is nodart_sdkormin_sdkfield at the package root. - Tab clicks are page loads, not toggles. Unlike PyPI where tabs are preloaded in the DOM, pub.dev tabs each navigate to a different URL. Always wait for a new page load after clicking a tab.
- robots.txt disallows browser search.
Disallow: /packages?q=means well-behaved agents should not use the browser search results page. UseGET /api/search?q=for all search. - Docs links only appear for versions that have documentation. Not every version in the versions list has a docs link (
a[title="Go to the documentation of..."]). Older versions and pre-releases often lack documentation. - Score, downloads, and likes are NOT in the main package endpoint.
GET /api/packages/{name}does not includegrantedPoints,likeCount, ordownloadCount30Days. These require a separate call toGET /api/packages/{name}/score. Always fetch/scorein parallel when comparing packages. /scoretags array encodes platform/SDK support. Thetags[]in the/scoreresponse includessdk:dart,sdk:flutter,platform:android,is:null-safe,license:bsd-3-clause, etc. This is a reliable machine-readable way to check compatibility without parsing the browser page.
Anti-Patterns
- NEVER use
versions[-1]orversions[versions.length-1]for the latest version — the array is oldest-first. Uselatest.versioninstead. - NEVER construct archive URLs by concatenating name + version — the
+encoding is inconsistent. Uselatest.archive_urlorversions[i].archive_urlfrom the API response directly. - NEVER use
/packages?q=for automated search — disallowed by robots.txt. UseGET /api/search?q={query}. - NEVER expect description or version from the search API — it returns names only. You need a second API call per package.
- NEVER look for Dart SDK version in a top-level field — it's at
latest.pubspec.environment.sdk, buried inside the pubspec object. - NEVER skip the
/scoreendpoint for package comparisons —grantedPoints,likeCount, anddownloadCount30Daysare available viaGET /api/packages/{name}/score. This is a separate call from/api/packages/{name}— the main package endpoint does NOT include these fields. - NEVER skip
/advisoriesfor security-sensitive comparisons —GET /api/packages/{name}/advisoriesreturns full CVE data in OSV format. An emptyadvisories[]array means no known vulnerabilities.
Freshness
| Skill verified | 2026-02-20 |
| API stable since | 2018 — /api/packages/{name}, /score, /advisories, /publisher all confirmed working 2026-02-20 |
| Selector stability | HIGH — server-rendered MPA with intentional class names (detail-info-box, detail-tabs-header, tab-content); no hashed classes |
| Breaking change risk | Low — pub.dev is the official Dart registry; UI changes infrequent |
| v1.1.0 changes | Added /score, /advisories, /publisher endpoints with real response shapes; corrected false anti-pattern that claimed score was browser-only; updated Compare task to fetch popularity data |
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

