Clean your 𝕏 feed

// Function to extract views from a post
console.log('starting cleaning x feed now...');
function extractViews(post) {
  // Find the views icon SVG
  const viewsIconPath = post.querySelector('path[d="M8.75 21V3h2v18h-2zM18 21V8.5h2V21h-2zM4 21l.004-10h2L6 21H4zm9.248 0v-7h2v7h-2z"]');
  
  if (!viewsIconPath) {
    return null;
  }

  // Find the nearest span with view count
  const viewsSpan = viewsIconPath.closest('a').querySelector('span span span');
  if (!viewsSpan) {
    return null;
  }

  const viewsText = viewsSpan.textContent;
  return viewsText;
}

// Function to check if views meet threshold using regex
function hasHighViews(viewsText) {
  // Match number followed by k or M (case insensitive)
  const regex = /(\d+(?:\.\d+)?)(k|M)/i;
  const match = viewsText.match(regex);
  
  if (!match) return false;
  
  const [_, num, unit] = match;
  const value = parseFloat(num);
  
  // Convert to thousands
  const thousands = unit.toLowerCase() === 'm' ? value * 1000 : value;
  
  // Must have at least 10k views
  return thousands >= 10;
}

// Function to process a single post
function processPost(post) {
  const views = extractViews(post);
  if (views && hasHighViews(views)) {
    return true;
  } else {
    // Remove posts that don't meet the criteria
    console.log('Removing post', post);
    // post.style.opacity = '0.2';
    post.style.visibility = 'hidden';
    return false;
  }
}

// Process initial posts
setTimeout(function() {
	
	const highViewPosts = [];
document.querySelectorAll('[data-testid="cellInnerDiv"]').forEach(post => {
  if (processPost(post)) {
    highViewPosts.push(post);
  }
});

// Create an observer to watch for new posts
const observer = new MutationObserver((mutations) => {
  mutations.forEach((mutation) => {
    mutation.addedNodes.forEach((node) => {
      if (node.nodeType === Node.ELEMENT_NODE && node.matches('[data-testid="cellInnerDiv"]')) {
        if (processPost(node)) {
          highViewPosts.push(node);
        }
      }
    });
  });
});

// Start observing the timeline for changes
const timeline = document.querySelector('[data-testid="primaryColumn"]');
if (timeline) {
  observer.observe(timeline, {
    childList: true,
    subtree: true
  });
}

}, 2000);

How it works

1) it waits for 2 seconds
2) it adds an observer to scan all new tweets appearing in your feed as you scroll down
3) it scans all posts and detects their views count
4) if a post has less than <10k views, it is removed from the feed

Why?

i feel like 𝕏 drains too much of my attention, but i want to stay in the loop.

Will it hack me?

No. You can copy the code to deepseek and ask if it is safe.

How to use it?

Install any custom JS browser extension (I'm using this one), open 𝕏, click on the extension, copy-paste the JS code there.

Who made it?

Alexander Isora, the indie maker. Follow me on 𝕏: https://x.com/alexanderisorax

Demo

Built on Unicorn Platform