Gator is a command-line RSS aggregator built with TypeScript and PostgreSQL. It lets multiple local users register, follow feeds, collect posts on an interval, and browse recent entries without switching between websites.
Following many engineering blogs usually means checking each source separately. Gator turns those feeds into one terminal workflow while keeping users, subscriptions, feeds, and posts in a relational database.
- Register users and switch the current local user
- Add RSS feeds and associate each feed with its creator
- Follow and unfollow feeds per user
- Fetch the least-recently-fetched feed on a configurable interval
- Retry failed feed requests up to three times
- Parse RSS and avoid duplicate posts through unique URLs
- Browse the newest posts from followed feeds
| Area | Technology |
|---|---|
| Language and runtime | TypeScript, Node.js |
| Database | PostgreSQL |
| Schema and queries | Drizzle ORM, Drizzle Kit, postgres |
| Feed parsing | fast-xml-parser |
| CLI execution | tsx, npm scripts |
Terminal command
↓
Command registry and handlers
↓
RSS fetcher / PostgreSQL query modules
↓
Drizzle schema: users, feeds, feed_follows, posts
The schema uses cascading relationships, unique feed and post URLs, and one unique follow per user/feed pair. The aggregator selects the feed that was fetched least recently, stores newly discovered posts, and updates that feed's fetch timestamps.
src/
index.ts CLI entry point and command registration
commands.ts Command handlers
config.ts ~/.gatorconfig.json reader/writer
parser.ts Duration parsing
rss/fetchFeed.ts RSS download and parsing
lib/db/schema.ts Drizzle table definitions
lib/db/queries/ User, feed, follow, and post queries
lib/db/scrape.ts Feed selection and post persistence
drizzle/ Generated SQL migrations
drizzle.config.ts Migration-tool database configuration
- Node.js 18 or newer and npm
- A running PostgreSQL database
git clone https://github.com/shady-stu/Build-Blog-Aggregator.git
cd Build-Blog-Aggregator
npm ciCreate ~/.gatorconfig.json:
{
"db_url": "postgres://<user>:<password>@localhost:5432/<database>",
"current_user_name": ""
}The runtime configuration above and the migration connection in drizzle.config.ts are separate. Before migrating, make sure both point to the same local PostgreSQL database. Do not commit real database credentials.
npm run migratenpm run generate creates a new migration after a schema change; it is not required for a normal first run because migrations are already committed.
Pass CLI arguments after -- so npm forwards them unambiguously.
| Command | Purpose |
|---|---|
npm run start -- register <username> |
Create a user and make that user current |
npm run start -- login <username> |
Switch to an existing user |
npm run start -- users |
List users and identify the current one |
npm run start -- addfeed "<name>" "<url>" |
Add and follow a feed |
npm run start -- feeds |
List all registered feeds |
npm run start -- follow "<feed-url>" |
Follow an existing feed |
npm run start -- following |
List feeds followed by the current user |
npm run start -- unfollow "<feed-url>" |
Stop following a feed |
npm run start -- agg <interval> |
Collect feeds continuously |
npm run start -- browse [limit] |
Show recent followed posts; default limit is 2 |
npm run start -- reset |
Delete every user and cascading data |
Intervals accept ms, s, m, or h, for example:
npm run start -- agg 30sWarning:
resetis destructive. It deletes all users and cascades through their feeds, follows, and posts.
npm run start -- register shady
npm run start -- addfeed "Hacker News" "https://news.ycombinator.com/rss"
npm run start -- agg 1mIn a second terminal:
npm run start -- browse 10The project currently has no automated test suite or test script. TypeScript can be checked without emitting build files:
npx tsc --noEmit- Migration and runtime database URLs must currently be kept in sync manually.
- Aggregation runs in the foreground and uses the local terminal process as its scheduler.
- Authentication is local-user selection, not password or token authentication.
- Add unit tests for duration parsing, RSS mapping, command validation, and database queries.
- Add structured logging and clearer handling for repeatedly failing feeds.