Socials#
A local-first CLI and GUI tool for aggregating, scoring, and analyzing social media feeds across multiple platforms. Written in OCaml 5.
All data is stored locally in SQLite. All analysis runs on your machine.
Supported Platforms#
- Bluesky (ATProto)
- Mastodon (ActivityPub, OAuth2)
- Pixelfed (OAuth2, Mastodon-compatible API)
- Lemmy (username/password auth)
- GitHub (Personal Access Token, received events)
Installation#
Requires OCaml 5.4+ and opam.
opam install . --deps-only
dune build
This produces two binaries: socials (CLI) and socials-ui (GUI).
CLI Usage#
socials <command> [options]
Setup#
| Command | Description |
|---|---|
init |
Initialize the database |
status |
Show database stats, migration state, and sync cursors |
auth <provider> |
Authenticate with a provider (bluesky, mastodon, github, lemmy, pixelfed) |
accounts |
List configured accounts |
Syncing#
| Command | Description |
|---|---|
sync |
Sync posts from a provider |
feeds |
List available Bluesky feeds |
sync flags:
-p, --provider— Provider to sync (bluesky, mastodon, github, lemmy, pixelfed)-f, --feed— Feed to sync (Mastodon/Pixelfed: home/local/global; Lemmy: subscribed/local/all)-n, --limit— Number of posts to sync (default: 50)--full— Force full resync, ignoring saved cursor--exif— Extract EXIF metadata from images-a, --all— Sync all configured accounts
Viewing#
| Command | Description |
|---|---|
view |
View posts from local database |
timeline |
Fetch live timeline from API |
top |
Show top-scored posts |
view flags:
-s, --source— Feed source: personal, local, global, all (default: all)-p, --provider— Filter by provider--sort— Sort order: date, score, engagement, likes (default: date)--media— Only show posts with media--min-score— Minimum score threshold--min-likes— Minimum likes threshold--type— Post type: original, reply, quote, all (default: all)--no-cw— Exclude posts with content warnings-n, --limit— Number of posts (default: 20)
Analysis#
| Command | Description |
|---|---|
score |
Run the scoring engine on all posts |
stats |
Analytics dashboard (flag: --period today|week|month|all) |
authors |
Author rankings (flag: --sort influence|posts|engagement|frequency) |
Posting#
| Command | Description |
|---|---|
post <text> |
Create a new post (flag: -p, --provider) |
GUI (socials-ui)#
A Raylib/Raygui immediate-mode desktop application.
- Card-based timeline showing author info, post content, engagement metrics, and embedded images
- Sort by date, score, engagement, or likes
- Search posts with
/ - Keyboard navigation: Up/Down/PageUp/PageDown to scroll, Tab to cycle sort, +/- to scale, Esc to quit
- Mouse: click cards, scroll wheel, clickable links
- DPI-aware with auto-detection and manual scaling
- EXIF metadata display for image embeds
Scoring Engine#
Running socials score computes a composite score (0–100) for each post from four weighted components:
Engagement (35%)#
Compares a post's engagement to its author's historical average. Reposts count 2x, replies 1.5x. A score of 50 means the post matches the author's average; scores above 50 indicate above-average engagement, up to 100 at 2x or more.
Content (25%)#
Heuristic points based on post attributes:
- Has media: +20
- Has links: +10
- Optimal length (50–500 chars): +20
- No content warning: +10
- Original post (not reply/repost): +15
- Images have alt text: +15
Author (20%)#
Evaluates the author's profile:
- Verified account: +20
- Follower/following ratio: up to +20
- Account age: +5/+10/+15 (30d/180d/365d+)
- Influence score (derived from follower count and average engagement): up to +30
- Bot penalty: -20
Recency (20%)#
Starts at 100, decays by 2 points per hour.
Author Stats#
The scoring engine also computes per-author statistics: average likes/reposts/replies, posting frequency, media and link percentages, and an influence score (log(followers) * 5 + avg_engagement * 2, capped at 100).
Architecture#
- Effects-based I/O: The library (
lib/) defines algebraic effects for HTTP, database, logging, time, and user input. The CLI (bin/) provides concrete handlers using Eio for async I/O,hcsfor HTTP, andsqlite3for storage. - Data path:
~/.local/share/socials/socials.db - JSON parsing:
simdjsont
License#
ISC