Migrating from 1.x to 2.x
This guide covers all breaking changes and new features when upgrading from Feedsmith 1.x to 2.x. Each breaking change is detailed with specific upgrade steps and examples.
IMPORTANT
Version 2.x introduces significant improvements including enhanced type safety, comprehensive feed generation support, and better namespace handling. However, it includes several breaking changes that require code updates.
Installation
Update your package to the latest 2.x version:
npm install feedsmith@latestBreaking Changes
parseFeed Return Type Property Rename
The parseFeed function now returns format instead of type to better align with industry terminology.
Before (1.x)
import { parseFeed } from 'feedsmith'
const result = parseFeed(feedContent)
console.log(result.type) // rss, atom, json, rdfAfter (2.x)
import { parseFeed } from 'feedsmith'
const result = parseFeed(feedContent)
console.log(result.format) // rss, atom, json, rdfMigration Steps
- Replace all instances of
result.typewithresult.format
RSS GUID Structure Change
RSS feed item GUIDs are now structured objects instead of plain strings to properly handle the isPermaLink attribute.
Before (1.x)
const rssFeed = parseRssFeed(content)
const guid = rssFeed.items?.[0]?.guid // stringAfter (2.x)
const rssFeed = parseRssFeed(content)
const guid = rssFeed.items?.[0]?.guid?.value // string
const isPermaLink = rssFeed.items?.[0]?.guid?.isPermaLink // boolean | undefinedMigration Steps
- Replace
item.guidwithitem.guid?.valuewhen accessing the GUID string - Use
item.guid?.isPermaLinkto check if the GUID is a permalink
Podcast Namespace contentLink Casing
The contentlink elements in the Podcast namespace are now properly cased as contentLink.
Before (1.x)
const contentLinks = feed.podcast?.contentlink // lowercaseAfter (2.x)
const contentLinks = feed.podcast?.contentLink // camelCaseMigration Steps
- Update access to podcast content links from
contentlinktocontentLink - This affects RSS feeds using the Podcast namespace
Enhanced Type System
The type system has been significantly enhanced with generic types and stricter type safety.
Before (1.x)
// Simple type definitions
interface RssFeed {
title: string
items: RssItem[]
}After (2.x)
// Generic type system with DateLike parameter
type RssFeed<TDate extends DateLike = string> = DeepPartial<{
title: string
items: RssItem<TDate>[]
// All fields are now optional at type level
}>Migration Steps
- All feed properties are now properly typed as optional, reflecting real-world feed variability
- Use optional chaining (
?.) when accessing feed properties - Consider using type guards for critical properties
- The enhanced typing may reveal previously hidden bugs in your code
RSS Enclosure Structure Change
RSS feed items now support multiple enclosures as an array instead of a single enclosure object.
Before (1.x)
const rssFeed = parseRssFeed(content)
const enclosure = rssFeed.items?.[0]?.enclosure // single Enclosure object
if (enclosure) {
console.log(enclosure.url)
console.log(enclosure.type)
console.log(enclosure.length)
}After (2.x)
const rssFeed = parseRssFeed(content)
const enclosures = rssFeed.items?.[0]?.enclosures // Array<Enclosure>
if (enclosures?.length) {
console.log(enclosures[0].url)
console.log(enclosures[0].type)
console.log(enclosures[0].length)
}Migration Steps
- Replace
item.enclosurewithitem.enclosures?.[0]for single enclosure access - Update code to handle multiple enclosures by iterating over the
enclosuresarray - Check for array length instead of truthy enclosure object
New Features
Comprehensive Feed Generation
Version 2.x introduces complete feed generation support:
import {
generateRssFeed,
generateAtomFeed,
generateJsonFeed,
generateOpml
} from 'feedsmith'
// Generate RSS feed
const rss = generateRssFeed({
title: 'My Blog',
link: 'https://example.com',
description: 'A blog about development',
items: [/* items */]
})
// Generate Atom feed
const atom = generateAtomFeed({
id: 'https://example.com/feed',
title: 'My Blog',
updated: new Date(),
entries: [/* entries */]
})Stylesheet Support
Add stylesheets to generated XML feeds:
const rss = generateRssFeed(feedData, {
stylesheets: [{
type: 'text/xsl',
href: '/feed.xsl'
}]
})Enhanced Namespace Support
New namespaces have been added:
- Dublin Core Terms (
dcterms): Extended metadata support - Well-Formed Web (
wfw): Comment API support - YouTube (
yt): YouTube-specific extensions
// Access new namespace data
const feed = parseRssFeed(content)
console.log(feed.dcterms?.created)
console.log(feed.wfw?.commentRss)
console.log(feed.yt?.channelId)Automatic Namespace Normalization
Custom namespace prefixes are automatically normalized to standard ones:
// Input: <custom:creator>John Doe</custom:creator>
// Automatically becomes: feed.dc.creatorMigration Checklist
Use this checklist to ensure a complete migration:
- Update
result.typetoresult.formatin allparseFeedcalls - Change
item.guidtoitem.guid?.valuefor RSS feeds - Change
item.enclosuretoitem.enclosures?.[0]for RSS feeds - Change
podcast.contentlinktopodcast.contentLink - Add optional chaining (
?.) for all feed property access - Test with your existing feeds to ensure proper parsing
- Consider utilizing new generation features
- Explore enhanced namespace support for richer data access