unashamed/ai
All projects · Chrome extension
Chrome extension · LinkedIn

LinkedIn Feed: Only 1st Connections & Follows

Strips your LinkedIn home feed down to only the content you actually asked for: posts from your 1st-degree connections and accounts you already follow. Promoted ads, Suggested posts, 2nd and 3rd-degree strangers, and posts that only appeared because someone reposted, liked or commented on them are hidden.

Version1.0.0
Permissionsstorage only
Runs onwww.linkedin.com, HTTPS, top frame
NetworkNone

How it decides

LinkedIn's feed uses rotating, obfuscated class names and no stable post id, so ordinary selectors break constantly. The extension keys off signals that survive:

  1. Post boundary. Every feed item is wrapped in an element with data-lazy-mount-id, and real posts begin their text with "Feed post".
  2. Connection degree. The actor header shows • 1st / • 2nd / • 3rd+. 1st-degree posts are always kept.
  3. Relationship buttons. For everyone else the decision is read from the real buttons LinkedIn renders (matched on aria-label): Following / Unfollow means kept, Follow … or Invite … to connect means hidden, and no relationship button at all means your own post or a Page you follow, so kept.

Always removed on top of that: ads ("Promoted by …", "Sponsored", or a Promoted label on a degree-less company post; a connection's post that merely contains the word "Promoted" is not hidden, that false positive was found and fixed), "Suggested" posts, "… follows this Page" items, and recommendation modules such as "Jobs recommended for you" and "People you may know". It can also switch the sort from Top to Recent, but only when the feed is on Top, so a manual choice is never overridden.

Options (toolbar popup)

What it can touch

Manifest entryWhy it is there
permissions: ["storage"]Your popup settings, kept in chrome.storage.sync. That is the only permission requested.
host_permissionsNone. Not requested, not needed.
content_scripts.matches: ["https://www.linkedin.com/*"]HTTPS only, and only linkedin.com. No other site is touched.
content_scripts.all_frames: falseTop-level document only; nothing is injected into embedded iframes.
run_at: "document_start"So the page is filtered as it renders rather than flashing unfiltered first.
content_security_policyscript-src 'self': no remote code, no eval, no inline script.
Zero network requests, zero data sent anywhere. No analytics, no telemetry, no remote config, no remote script. The only network traffic is the site itself loading, exactly as it would without the extension. Your settings live in chrome.storage.sync (so they follow your Chrome profile) and nothing else is stored.

What it does not do

Honest caveats

Security

Follows the repo's shared security guidelines (the OWASP Browser Extension Vulnerabilities Cheat Sheet): storage is the only permission, the content script runs HTTPS-only in the top frame, a strict CSP forbids remote code, no innerHTML or eval, no network calls, and popup↔page messaging checks sender.id. A static audit (tests/owasp-audit.mjs) enforces all of that on every extension in the repo.

Install

  1. Download or clone the repo.
  2. Open chrome://extensions and turn on Developer mode (top right).
  3. Click Load unpacked and choose the chrome-extensions/linkedin-remove-anything-i-dont-follow folder.
View the source and README →