High-performance RSS/Atom/JSON Feed parser written in Rust, with Python and Node.js bindings.
- Multi-format support — RSS 0.9x, 1.0, 2.0 / Atom 0.3, 1.0 / JSON Feed 1.0, 1.1
- Tolerant parsing — Handles malformed feeds gracefully with
bozoflag pattern - HTTP fetching — Built-in URL fetching with compression (gzip, deflate, brotli)
- Conditional GET — ETag/Last-Modified support for bandwidth-efficient polling
- Podcast support — iTunes and Podcast 2.0 namespace extensions
- Multi-language bindings — Native Python (PyO3) and Node.js (napi-rs) bindings
- Familiar API — Inspired by Python's feedparser, easy to migrate existing code
| Format | Versions | Status |
|---|---|---|
| RSS | 0.90, 0.91, 0.92, 1.0, 2.0 | ✅ Full support |
| Atom | 0.3, 1.0 | ✅ Full support |
| JSON Feed | 1.0, 1.1 | ✅ Full support |
| Namespace | Description |
|---|---|
| Dublin Core | Creator, date, rights metadata |
| Content | Encoded HTML content |
| Media RSS | Media attachments and metadata |
| iTunes | Podcast metadata (author, duration, explicit) |
| Podcast 2.0 | Chapters, transcripts, funding |
| Syndication | Update schedule (period, frequency, base) |
| GeoRSS | Geographic location data (point, line, polygon, box) |
| Creative Commons | License information with rel="license" links |
cargo add feedparser-rsOr add to your Cargo.toml:
[dependencies]
feedparser-rs = "0.2"Important
Requires Rust 1.88.0 or later (edition 2024).
npm install feedparser-rs
# or
yarn add feedparser-rs
# or
pnpm add feedparser-rspip install feedparser-rsuse feedparser_rs::parse;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let xml = r#"
<?xml version="1.0"?>
<rss version="2.0">
<channel>
<title>Example Feed</title>
<link>https://example.com</link>
<item>
<title>First Post</title>
<link>https://example.com/post/1</link>
</item>
</channel>
</rss>
"#;
let feed = parse(xml.as_bytes())?;
println!("Version: {}", feed.version.as_str()); // "rss20"
println!("Title: {:?}", feed.feed.title);
println!("Entries: {}", feed.entries.len());
for entry in &feed.entries {
println!(" - {:?}", entry.title);
}
Ok(())
}use feedparser_rs::fetch_and_parse;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let feed = fetch_and_parse("https://example.com/feed.xml")?;
println!("Fetched {} entries", feed.entries.len());
Ok(())
}Tip
Use fetch_and_parse for URL fetching with automatic compression handling (gzip, deflate, brotli).
import { parse, fetchAndParse } from 'feedparser-rs';
// Parse from string
const feed = parse('<rss version="2.0">...</rss>');
console.log(feed.version); // 'rss20'
console.log(feed.feed.title);
console.log(feed.entries.length);
// Fetch from URL
const remoteFeed = await fetchAndParse('https://example.com/feed.xml');See Node.js API documentation for complete reference.
import feedparser_rs
# Parse from bytes or string
d = feedparser_rs.parse(b'<rss>...</rss>')
print(d.version) # 'rss20'
print(d.feed.title)
print(d.bozo) # True if parsing had issues
print(d.entries[0].published_parsed) # time.struct_timeNote
Python bindings provide time.struct_time for date fields, matching feedparser's API for easy migration.
| Feature | Description | Default |
|---|---|---|
http |
Enable URL fetching with reqwest (gzip/deflate/brotli support) | Yes |
To disable HTTP support and reduce dependencies:
[dependencies]
feedparser-rs = { version = "0.2", default-features = false }| Crate | Description | Package |
|---|---|---|
feedparser-rs |
Core Rust parser | crates.io |
feedparser-rs-node |
Node.js bindings | npm |
feedparser-rs-py |
Python bindings | PyPI |
# Install cargo-make
cargo install cargo-make
# Run all checks (format, lint, test)
cargo make ci-all
# Run tests with coverage
cargo make coverage
# Run benchmarks
cargo make benchSee all available tasks:
cargo make --list-all-stepsMeasured on Apple M1 Pro, parsing real-world RSS feeds:
| Feed Size | Time | Throughput |
|---|---|---|
| Small (2 KB) | 10.7 µs | 187 MB/s |
| Medium (20 KB) | 93.6 µs | 214 MB/s |
| Large (200 KB) | 939 µs | 213 MB/s |
Format detection: 128 ns (near-instant)
| Operation | feedparser-rs | Python feedparser | Speedup |
|---|---|---|---|
| Parse 20 KB RSS | 0.09 ms | 8.5 ms | 94x |
| Parse 200 KB RSS | 0.94 ms | 85 ms | 90x |
Tip
Run your own benchmarks with cargo bench or compare against Python with cargo make bench-compare.
Minimum Supported Rust Version: 1.88.0 (edition 2024).
MSRV increases are considered breaking changes and will result in a minor version bump.
Licensed under either of:
at your option.
Contributions are welcome! Please read our Contributing Guide before submitting a pull request.
This project follows the Rust Code of Conduct.