feed2md converts RSS and Atom feeds into clean Markdown.
It ships as:
- a library package:
feed2md - a CLI package:
feed2md-cli
- Quickly archive feed updates as Markdown
- Generate changelog-like digests from feeds
- Reuse the parser + markdown renderer in your own tooling
Library (npm)
npm install feed2mdLibrary (pnpm)
pnpm add feed2mdCLI (npm)
npx feed2md-cli <feed-url> [options]CLI (pnpm)
pnpm dlx feed2md-cli <feed-url> [options]npm (npx)
npx feed2md-cli <feed-url> [options]pnpm
pnpm dlx feed2md-cli <feed-url> [options]Options:
-o, --output <file>: write output to file--limit <number>: limit article count--no-summary: skip preview text--summary-max-length <number>: truncate summary preview--template <preset>: built-in template preset (shortorfull, default:short)--template-file <path>: load a custom Eta template file
Examples:
# print to stdout
npx feed2md-cli https://example.com/feed.xml
# write to a file
npx feed2md-cli https://example.com/feed.xml --output feed.md
# limit items and shorten previews
npx feed2md-cli https://example.com/feed.xml --limit 5 --summary-max-length 140
# render with full metadata template
npx feed2md-cli https://example.com/feed.xml --template full
# render with a custom Eta template file
npx feed2md-cli https://example.com/feed.xml --template-file ./templates/feed.etaimport { feed2md } from 'feed2md'
const markdown = await feed2md('https://example.com/feed.xml', {
limit: 10,
includeSummary: true,
summaryMaxLength: 220,
templatePreset: 'short', // default
})
console.log(markdown)Fetches a feed and returns Markdown.
Options (Feed2MdOptions):
fetchImpl?: typeof fetchincludeSummary?: boolean(default:true)limit?: numbersummaryMaxLength?: number(default:280)templatePreset?: 'short' | 'full'(default:'short')template?: string(custom Eta template content; overridestemplatePreset)
Parses RSS/Atom XML into a normalized ParsedFeed object.
Normalized data now includes feed/item metadata such as:
- links (
link+links[]with rel/type) - ids (
guid/id) - authors (
dc:creator/ Atomauthor) - categories (RSS
category, Atomcategory term) - media payloads (
media:content,media:group,media:credit,media:description) - feed-level metadata (
description,language,copyright,generator,ttl,image)
Renders normalized feed data to Markdown.
Supports:
toMarkdown(feed, 5)(legacy numeric limit)toMarkdown(feed, { limit, includeSummary, summaryMaxLength, templatePreset, template })
Built-in templates:
short(default): compact output for title/link/date/summaryfull: includes all normalized feed/item metadata
Custom templates use Eta syntax and receive context as it:
it.feed: rendered feed view (title,source,fullLines)it.items: rendered item views (header,shortLines,fullLines)it.raw: raw normalizedParsedFeedit.includeSummary: effective summary toggleit.preset: selected preset (shortorfull)
See docs/SAMPLES.md for concrete XML input and rendered markdown output examples.
Often yes, but it depends on the feed publisher.
Common fields used by feed2md:
- RSS:
description,content:encoded,content,dc:description,dc:creator,category,guid,media:* - Atom:
summary,content,subtitle,author,category,id,link,updated,published
If no summary-like field exists, output includes title/link/published date only.
pnpm install
pnpm lint
pnpm test
pnpm buildUseful scripts:
pnpm formatpnpm format:checkpnpm changesetpnpm test:watch
This repo uses Changesets + GitHub Actions.
-
Add a changeset in feature/fix PRs:
pnpm changeset
-
Merge to
main. TheReleaseworkflow will open/update a version PR. -
Merge the version PR to publish to npm.
- Contribution guide: CONTRIBUTING.md
- Code of conduct: CODE_OF_CONDUCT.md
- Security policy: SECURITY.md
- Project roadmap/plan: docs/PROJECT_PLAN.md
MIT. See LICENSE.