Review guidelines
Route Configuration
Example Format: The
examplefield must start with/and be a working RSSHub route path (e.g.,/example/route), not a full URL or source website URL.Route Name: Do NOT repeat the namespace name in the route name. The namespace is already defined in
namespace.ts.Radar Source Format: Use relative paths without
https://prefix inradar[]. source. Example:source: ['www.example.com/path']instead ofsource: ['https://www.example.com/path'].Radar Target: The
radar[].targetmust match the route path. If the source URL does not contain a path parameter, do not include it in the target.Namespace URL: In
namespace.ts, theurlfield should NOT include thehttps://protocol prefix.Single Category: Provide only ONE category in the
categoriesarray, not multiple.Unnecessary Files: Do NOT create separate
README.mdorradar.tsfiles. Put descriptions inRoute['description']and radar rules inRoute['radar'].Legacy Router: Do NOT add routes to
lib/router.js- this file is deprecated.Features Accuracy: Set
requirePuppeteer: trueonly if your route actually uses Puppeteer. Do not mismatch feature flags.Maintainer GitHub ID: The
maintainersfield must contain valid GitHub usernames. Verify that the username exists before adding it.
Code Style
Naming Convention: Use
camelCasefor variable names in JavaScript/TypeScript. Avoidsnake_case(e.g., usevideoUrlinstead ofvideo_url).Type Imports: Use
import type { ... }for type-only imports instead ofimport { ... }.Import Sorting: Keep imports sorted. Run autofix if linter reports import order issues.
Unnecessary Template Literals: Do not use template literals when simple strings suffice (e.g., use
'plain string'instead of`plain string`).Avoid Loading HTML Twice: Do not call
load()from cheerio multiple times on the same content. Reuse the initial$object.Async/Await in Close: When closing Puppeteer pages/browsers, use
await page.close()andawait browser.close()instead of non-awaited calls.No Explicit Null: No need to explicitly set a property to
nullif it does not exist - just omit it.Valid Item Properties: Only use properties defined in lib/types. ts. Custom properties like
avatar,biowill be ignored by RSSHub.String Methods: Use
startsWith()instead ofincludes()when checking if a string begins with a specific prefix.Simplify Code: Combine multiple conditional assignments into single expressions using
||or??operators when appropriate.
Data Handling
Use Cache: Always cache the returned results when fetching article details in a loop using
cache.tryGet().Description Content: The
descriptionfield should contain ONLY the main article content. Do NOT includetitle,author,pubDate, or tags indescription- they have their own dedicated fields.Category Field: Extract tags/categories from articles and place them in the
categoryfield, not indescription.pubDate Field: Always include
pubDatewhen the source provides date/time information. Use theparseDateutility function.No Fake Dates: Do NOT use
new Date()as a fallback forpubDate. If no date is available, leave it undefined. See No Date documentation.No Title Trimming: Do not manually trim or truncate titles. RSSHub core handles title processing automatically.
Unique Links: Ensure each item's
linkis unique as it will be used asguid. Avoid fallback URLs that could cause duplicateguidvalues.Human-Readable Links: The feed
linkfield should point to a human-readable webpage URL, NOT an API endpoint URL.
API and Data Fetching
Prefer APIs Over Scraping: When the target website has an API (often found by scrolling pages or checking network requests), use the API endpoint instead of HTML scraping.
JSON Parsing: When using
ofetch,JSON.parseis automatically applied. Do not manually decode JSON escape sequences like\u003C.No Page Turning: RSS feeds should only request the first page of content. Do not implement pagination parameters for users.
Use Common Parameters: Use RSSHub's built-in common parameters like
limitinstead of implementing custom query parameters for limiting entries.No Custom Query Parameters: Avoid using querystring parameters for route configuration. Use path parameters (
:param) instead.No Custom Filtering: Do not implement custom tag/category filtering in routes. Users can apply filtering using common parameters.
Avoid Dynamic Hashes: If an API requires a hash that changes across builds, extract it dynamically from the webpage rather than hardcoding it.
User-Agent: Use RSSHub's built-in User-Agent (
config.trueUA) when making requests that need realistic browser headers.
Media and Enclosures
Valid MIME Types: The
enclosure_typemust be a valid MIME type as defined in RFC specifications. For example,video/youtubeis NOT valid - use actual video file URLs with proper types likevideo/mp4.Direct Media URLs:
enclosure_urlmust point directly to downloadable media files (e.g.,.mp4,.mp3), not to web pages containing media.Video Poster: Use the HTML5
<video>element'sposterattribute for video thumbnails instead of adding separate<img>elements.No Referrer Policy in Routes: Do not add
referrerpolicyattributes to images/videos - RSSHub middleware handles this automatically.
Puppeteer Usage
Limit Request Types: Do not allow every type of request through Puppeteer. Explicitly provide a list of allowed request types (e.g.,
document) to avoid wasting resources on images, scripts, etc.Use Selectors, Not Delays: Do not use fixed
setTimeoutdelays. Usepage.waitForSelector()instead to wait for specific elements.Avoid Multiple Sessions: Do not call Puppeteer inside
Promise.all()loops - this creates multiple browser sessions and dramatically increases resource usage.Do Not Bypass Empty Checks: Do not return empty arrays with custom messages to bypass RSSHub's [internal checks](https://github.com/DIYgod/RSSHub/blob/master/lib/middleware/parameter. ts#L72) for empty items. This makes it hard for users and maintainers to know if a feed is broken.
Default Values and Examples
Preserve Default Values: Do not change documented default values for existing route parameters unless the current default is broken.
Preserve Working Examples: Do not modify existing route examples unless they no longer work.
Route Parameters: The
parametersobject keys must match the actual path parameters defined in the route path. Do not add non-existent parameters.
Error Handling
Error Messages: Use clear, actionable error messages that help users understand what went wrong.
Resolve All Review Comments: Before requesting re-review, ensure ALL previous review comments are addressed, not just some of them.
Code Organization
Move Functions Up: Move function definitions to the highest possible scope. Avoid defining functions inside loops or callbacks when they can be defined at module level.
No Await in Loops: Avoid using
awaitinside loops when possible. UsePromise.all()with proper concurrency control instead.Check URL Validity: Before using URLs from config files or namespaces, verify they don't return 404 errors.
Comments Language: Write code comments in English for consistency and accessibility.
Parentheses in Arrow Functions: Always use parentheses around arrow function parameters, even for single parameters.