DEV Community

Cover image for I Built NetPrune: A Rust Tool to Clean Up My 12,000+ LinkedIn Connections
Altug Tatlisu
Altug Tatlisu

Posted on

I Built NetPrune: A Rust Tool to Clean Up My 12,000+ LinkedIn Connections

How I used Rust to analyze and filter 12,613 LinkedIn connections, and what I learned about automation, ToS violations, and building developer tools

The Problem: 12,613 Connections and Counting

Let me tell you a story about accidentally collecting too many LinkedIn connections and deciding to do something about it.

I run a blockchain company, and over the years, I've been pretty liberal with LinkedIn connection requests. My thinking was simple: more connections equals more opportunities, right?

Wrong.

My feed became a mess. For every interesting blockchain developer or tech entrepreneur, I had 10 crypto scammers, NFT shillers, and completely unrelated professionals. Finding actual valuable content was like searching for a needle in a haystack.

I needed to clean house. But clicking through 7,000+ profiles manually? No thanks.

The Solution: Build It Myself

I'm a Rust developer, so naturally, my solution was to build a tool.

The plan was simple:

  1. Export my LinkedIn connections as CSV
  2. Filter them based on keywords (blockchain, Web3, Rust, and similar terms)
  3. Automatically remove the irrelevant ones

Spoiler alert: Step 3 didn't go as planned. But let's start from the beginning.

Building NetPrune

Part 1: The Analysis Tool (This Actually Worked)

The first part was straightforward. LinkedIn lets you export your connections as a CSV file. I wrote a Rust parser to read it:

pub fn parse_csv(path: &str) -> Result<Vec<Connection>> {
    let mut reader = csv::Reader::from_path(path)?;
    let mut connections = Vec::new();

    for result in reader.deserialize() {
        let connection: Connection = result?;
        connections.push(connection);
    }

    Ok(connections)
}
Enter fullscreen mode Exit fullscreen mode

Then I built a keyword-based filter. If someone's position or company contained terms like "blockchain," "crypto," or "Rust developer," they were marked as "relevant." Everyone else was "unwanted."

The Results:

  • Total connections: 12,613
  • Relevant connections (blockchain and tech): 5,101 (40.4%)
  • Unwanted connections: 7,512 (59.6%)
  • Ghost connections (deactivated accounts): 2,750

Holy crap. 60% of my network was noise.

Part 2: The Automation Attempt (This Did Not Work)

Here's where things got interesting. I thought I could use headless_chrome to automate the removals.

I spent hours:

  • Inspecting LinkedIn's DOM structure
  • Finding CSS selectors
  • Writing click automation code
  • Debugging why buttons wouldn't click
fn remove_single_connection(&self, tab: &Tab, profile_url: &str) -> Result<()> {
    tab.navigate_to(profile_url)?;

    // Click "More actions" button
    let more_button = tab.find_element("button[aria-label*='More actions']")?;
    more_button.click()?;

    // Click "Remove connection"
    let remove_button = tab.find_element("div[aria-label*='Remove connection']")?;
    remove_button.click()?;

    // Confirm removal
    let confirm_button = tab.find_element("button[data-test-dialog-primary-btn]")?;
    confirm_button.click()?;

    Ok(())
}
Enter fullscreen mode Exit fullscreen mode

It opened the browser. It navigated to profiles. But the actual removal? Didn't work.

LinkedIn's DOM is a nightmare:

  • Class names change constantly
  • Menu items don't exist in the DOM until clicked
  • Elements disappear when you lose focus
  • Everything is dynamically rendered with Ember.js

But here's the real problem...

The Wake-Up Call: Terms of Service

I showed my progress to Claude (yes, I use AI assistants for code review), and it hit me with a reality check:

"LinkedIn's User Agreement explicitly prohibits automated access and scraping. Section 8.2 and 8.3. You could get banned."

Oh.

I looked it up. Claude was right. Even if I got the automation working perfectly, I would be:

  • Violating LinkedIn's Terms of Service
  • Risking account suspension
  • Teaching others to do the same

Not cool.

The Pivot: Analysis Tool Only

So I made a decision: NetPrune would be an analysis and filtering tool, not an automation tool.

The automation code is still there for educational purposes, but with prominent warnings everywhere:

Warning: Browser automation violates LinkedIn Terms of Service
Use this tool for ANALYSIS ONLY. Remove connections manually.
Enter fullscreen mode Exit fullscreen mode

The recommended workflow became:

  1. Use NetPrune to analyze your connections
  2. Export the filtered CSV
  3. Use LinkedIn's official bulk selection features
  4. Remove connections manually (spread over days or weeks)

Is it slower? Yes. Is it legal and safe? Also yes.

What I Learned

Sometimes "Good Enough" Beats "Perfect"

My original plan was full automation. The final product is a CSV analysis tool with optional (but risky) automation. And you know what? The analysis part alone is incredibly valuable.

Read The Terms of Service

Seriously. I almost published a tool that could get users banned. Always check if what you're building violates platform policies.

Rust is Perfect for CLI Tools

Zero runtime dependencies, fast CSV parsing, great error handling with anyhow, and clap for CLI parsing made this project enjoyable to build.

Documentation Matters

I built:

  • A retro-punk styled landing page
  • GitHub Wiki with detailed guides
  • Comprehensive Rust documentation
  • Safety warnings everywhere

Good documentation turns a "cool hack" into a "useful tool."

The Final Product

NetPrune is now live:

Install it:

cargo install netprune
Enter fullscreen mode Exit fullscreen mode

Use it:

netprune analyze --input Connections.csv
netprune export --input Connections.csv --output unwanted.csv
Enter fullscreen mode Exit fullscreen mode

Should You Use It?

If you have thousands of LinkedIn connections and want to:

  • Analyze your network statistically
  • Filter by keywords or industries
  • Export lists for manual review

Then yes! NetPrune is safe, legal, and useful.

If you want to auto-remove 5,000 connections overnight? Please don't. LinkedIn will ban you, and I'll feel guilty.

What's Next?

I'm considering:

  • Better filtering algorithms (possibly ML-based scoring)
  • Web UI for easier connection review
  • Integration with other professional networks
  • Analytics dashboard

But for now, NetPrune does one thing well: helping you understand your network so you can make informed decisions about who to keep.


Have you ever had to clean up a massive social network? How did you approach it? Drop a comment below!

Post-script: Yes, I'm still manually removing those 7,000+ connections. It's tedious. Send help.


Links

Built with love and Rust by ChronoCoders

Top comments (2)

Collapse
 
cyber8080 profile image
Cyber Safety Zone

Cool project — nice work building NetPrune to clean up 12,000+ connections. (That’s no small feat.)

I totally agree: having a leaner, more relevant network often beats having thousands of stale connections. It’s a reminder that sometimes “less is more” — and a simple tool can make a huge difference.

Thanks for sharing your experience and code — this is the kind of practical, no-fluff work that gets real improvements done.

Collapse
 
elonmusk28 profile image
Elon Reeve Musk

That’s great news.