Migration 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@latest
Breaking 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, rdf
After (2.x)
import { parseFeed } from 'feedsmith'
const result = parseFeed(feedContent)
console.log(result.format) // rss, atom, json, rdf
Migration Steps
- Replace all instances of
result.type
withresult.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 // string
After (2.x)
const rssFeed = parseRssFeed(content)
const guid = rssFeed.items?.[0]?.guid?.value // string
const isPermaLink = rssFeed.items?.[0]?.guid?.isPermaLink // boolean | undefined
Migration Steps
- Replace
item.guid
withitem.guid?.value
when accessing the GUID string - Use
item.guid?.isPermaLink
to 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 // lowercase
After (2.x)
const contentLinks = feed.podcast?.contentLink // camelCase
Migration Steps
- Update access to podcast content links from
contentlink
tocontentLink
- 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.enclosure
withitem.enclosures?.[0]
for single enclosure access - Update code to handle multiple enclosures by iterating over the
enclosures
array - 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.creator
Migration Checklist
Use this checklist to ensure a complete migration:
- Update
result.type
toresult.format
in allparseFeed
calls - Change
item.guid
toitem.guid?.value
for RSS feeds - Change
item.enclosure
toitem.enclosures?.[0]
for RSS feeds - Change
podcast.contentlink
topodcast.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