- Published on
I linted my own blog for AI-sounding writing. Here is what worked and what I skipped

- Authors

- Name
- Nadim Tuhin
- @nadimtuhin
On this page
I write a lot of my posts with an AI model in the loop, so I wanted to know how much generic phrasing had leaked in. A list of sentences to rewrite was the goal, with no detector score involved.
This is what I ran, what it found in my own posts, and the check that now runs on every commit.
The tools I looked at and skipped
The first search result for "make AI text sound human" is a pile of paid tools. I read through the list and set most of them aside.

AI detectors (GPTZero, Originality, Turnitin, Quetext, Smodin). Independent tests put them well below their own marketing numbers, and they flag real human writing. A Stanford study found they labelled most essays by non-native English writers as AI. I am a Bangladeshi engineer writing in English, so a detector could easily flag my own sentences. Nobody who hires me will run one.
Paid humanizers (HixBypass, StealthWriter, WriteHuman, Phrasly and similar). They rewrite text to dodge detectors. They mostly shuffle words, and the output reads worse. The "tested and ranked" pages that praise them are often affiliate sites, so I gave those little weight.
Cheap shared-login seats. Some lists sell premium tools for a few dollars a month. They share one account between many people, which breaks the vendor's terms, and you would be signing in from the same browser you use for your real accounts.
What I used instead
slopless is an npm package built on textlint. It runs locally, makes no model calls, and prints JSON. It checks for the contrast-reframe pattern, stock phrases such as "tip of the iceberg", and filler words. Its dependencies are textlint and a few text libraries, and it has no postinstall script.
Harper is an offline grammar checker with editor plugins. It suits a second-language writer because it runs on your machine.
Vale with an AI-tells style is the heavier option if you want rules you can edit. I did not need it yet.
What it found in 31 posts
slopless only reads .md files, and my posts are .mdx. I copied each post to a temp folder, removed the frontmatter and code blocks, and ran it there. It reported 37 findings.
Some were noise. It flagged curly quotes in my poems and title case on product names. I ignored those.
The rest were real. This is the worst offender, from a post about software in 2026:

- "What changed wasn't the AI. It was my mental model." became "What changed was my mental model."
- "Adapting to coding agents is just the tip of the iceberg." became "Adapting to coding agents is the easy 10%."
- "Here's what I'm actually using in 2026:" lost the word "actually".
Across 13 posts I made 25 edits. The word "actually" went from five uses to one in that post. The leftovers were false positives and one sentence about webhook delivery guarantees, which I reworded anyway so the check would pass cleanly.
I did not try to reach zero. Fixing every "not X, but Y" sentence would flatten how I write, and some contrasts are the point.
The check that runs on commit
A one-off clean-up fades. A check on every commit does not.

scripts/lint-prose.mjs does the same copy-and-strip step, runs slopless, drops the noisy rules, skips the poems, and prints the file, line number and sentence. lint-staged runs it on any staged post under data/blog/. If it finds something, the commit stops.
To test it I staged a post with a deliberate contrast-reframe sentence added. The commit was blocked and the output named the line. I removed the test line afterwards and confirmed the file was clean.
git commit --no-verify skips the check when I disagree with it. A hook that cannot be bypassed gets deleted.
What I would do again
- Start with a list of sentences to rewrite, not a score.
- Ignore the rules that flag your own style on purpose.
- Fix the clear cases and stop when only false positives are left.
- Put the check in a hook so new posts get it too.
The whole thing is one script and one dev dependency. The paid tools I skipped run from a few dollars to about fifteen a month, and I do not think they would have told me anything this did not.