A viewer and naive analysis tool for social feeds (atproto and activitypub)
OCaml 99.1%
Dune 0.3%
Other 0.6%
15 1 0

Clone this repository

https://tangled.org/gdiazlo.tngl.sh/socials https://tangled.org/did:plc:g2nj54o5lr36vbtw55n7xktw/socials
git@tangled.org:gdiazlo.tngl.sh/socials git@tangled.org:did:plc:g2nj54o5lr36vbtw55n7xktw/socials

For self-hosted knots, clone URLs may differ based on your setup.

Download tar.gz
README.md

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, hcs for HTTP, and sqlite3 for storage.
  • Data path: ~/.local/share/socials/socials.db
  • JSON parsing: simdjsont

License#

ISC