kleampa/not-paid: a fading page as an unpaid invoice reminder
Client did not pay? Add opacity to the body tag and decrease it every day until their site completely fades away
At a glance
- What is it?
- The not-paid repository ships a single JavaScript file that lowers the opacity of a client's site a little each day after an agreed due date. It is a protest measure, not an invoicing system, and the README is blunt about what it will not accept.
- Who is it for?
- Adopt not-paid only if you control the deployment and understand that the fade is a visible, reversible pressure tactic rather than a payment mechanism. Do not use it on a site you no longer administer, on a client who has already disputed the invoice, or anywhere a sudden visual change could be read as a security incident.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 52 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The unpaid invoice problem not-paid addresses
Freelance web work has an awkward failure mode. The site is live, the client is using it, and the invoice sits unpaid. Chasing by email produces nothing visible. Taking the site down is a hard, hostile move that often ends the relationship and can invite a dispute about whether work was delivered. not-paid occupies the space between those two options. The page keeps working, but it visibly deteriorates on a schedule the developer sets in advance.
It is aimed at a narrow audience: people who built or maintain a client's front end, still have write access to it, and want a reminder that the client cannot ignore. The README frames the whole project in one line, asking whether the client did not pay and then describing the effect: add opacity to the body tag and decrease it every day until the site fades away. The tool is a lever, and the README treats it as one.
The repository is tiny. The top level holds README.md and not-paid.js, and the primary language is JavaScript. There is no build step, no package manifest, no test suite and no configuration file. That is the entire surface area, which is both the appeal and the reason it will not fit every situation.
How the fade is driven from two variables
The mechanism is deliberately primitive. The script defines a due date and a deadline in days, then computes how far into that window the current date sits and applies a corresponding opacity to the document body. Two variables sit at the top of the file under a comment telling you to change them as you wish, followed by a second comment telling you to stop changing things after that point.
The README shows the block exactly as it appears in the source:
/* change these variables as you wish */
var due_date = new Date('2017-02-27');
var days_deadline = 60;
/* stop changing here */In that example the fade begins from 2017-02-27 and runs for 60 days. The arithmetic is date subtraction: elapsed time since the due date, divided by the deadline, mapped onto the opacity range. Because the calculation happens in the browser at load time, the effect depends on the visitor's clock. A visitor with a badly wrong system date sees a different opacity than everyone else. Nothing is stored server-side and no state persists between visits, so the fade is recomputed fresh on every page load.
The body tag is the target. That means the script does not need to know anything about the site's markup, framework or stylesheet. It reaches for the one element every HTML document has. The trade-off is that opacity on the body affects everything inside it, including text, images and interactive controls, so the page does not merely look faded, it becomes progressively harder to read and use. That is the point, and it is worth being explicit about it before you deploy.
Loading not-paid.js in the head
The README gives one installation instruction: load the not-paid.js file in the head of the document. There is no npm package, no CDN reference and no bundler configuration documented. You place the file where the site can serve it and reference it from the head.
The first step is to edit the two variables at the top of not-paid.js so they match your agreement. The README's own block is the template:
/* change these variables as you wish */
var due_date = new Date('2017-02-27');
var days_deadline = 60;
/* stop changing here */Substitute your own date for 2017-02-27 and your own number of days for 60. The README does not state what happens if the deadline is set to zero or if the due date is in the past, so test the arithmetic yourself before you ship it.
The second step is the head reference. The README gives the instruction to load the file in the head but no literal snippet, so the only form it documents is the plain script tag pointing at not-paid.js, which you place inside the head element of the document. After deploying, load the client's page and check the body element in your browser's developer tools. You should see an inline opacity value on the body tag that reflects how many days have passed since the due date. If the value is 1 or the property is absent, either the date is still in the future or the file is not being served from the path you referenced. The README documents no other verification step, so this manual check is the whole test procedure.
The limitations the README does not discuss
The script is trivially removable, and that is its largest weakness as a pressure tactic. Anyone with access to the site's source can delete the script tag or set the body opacity back to 1 in a stylesheet. If the client has a developer, the fade may last minutes. The README does not address this, and there is no obfuscation, no server-side enforcement and no fallback if the script is stripped.
There is also a legal and professional exposure the repository does not mention. Deliberately degrading a live site that customers may be using is a different act from withholding delivery. The repository listing does not state a licence, so the terms under which you may redistribute or modify not-paid.js are unclear. Treat that as an open question to resolve before shipping it to a client.
The project is also effectively frozen as a collaboration. The README states plainly that no pull requests or issues will be accepted. The last push to the default branch was on 2026-08-08, which is recent enough that the code has not been abandoned, but the maintainer has closed the door on contributions. If you find a bug, you fix it in your own copy. There are no releases listed, so there is no versioned artifact to pin against. You are vendoring a file, not depending on a package.
Finally, the fade is global. It does not distinguish between the client's admin screens and their customers' storefront. If the site serves paying end users, the script punishes the wrong people. That is the clearest case where not-paid is the wrong tool.
Alternatives: platform versions and doing nothing
The README points to several reimplementations for other stacks. A WordPress plugin exists at SurfEdge/not-paid-wp, an Android version at theapache64/faded, a Windows Forms version at g-otn/winforms-not-paid, a Flutter version at krishnakumarcn/faded, an iOS SwiftUI version at vfrascello/not-paid-ios, and an Angular version at CleitonJB/not-paid. These are not competitors in the usual sense; they are ports of the same idea into environments where dropping a script tag into a head element is not how you ship code.
The practical difference is packaging. The WordPress plugin installs through the platform's plugin system and can be deactivated from the admin dashboard, which also means the client can deactivate it just as easily if they have administrator access. The mobile versions apply the fade to an app rather than a website, which changes the audience entirely: an app user who sees a fading interface has no relationship to the unpaid invoice. Choosing between the original and a port is mostly a question of which surface you still control.
The other alternative is the one the README implies with its closing line about using a payment platform next time. Escrow and milestone billing remove the situation the script exists to handle. That is not a technical comparison, but it is the honest one: not-paid is a remedy for a process failure, and a process that pays on delivery does not need a remedy.
Maintenance cost and licence position
The upgrade cost is close to zero and also close to unmeasurable. There are no releases in the repository, so there is no changelog to read and no version number to track. The default branch last received a push on 2026-08-08. If you vendor not-paid.js into a project, you are copying a file, and the only way to know whether it changed upstream is to diff it yourself. That is a real cost in a team setting, where dependency updates usually flow through a package manager and a lockfile.
The README also carries sponsorship material, including a GitAds block and a verification comment, plus two postscripts recommending a payment platform and a travel eSIM service. None of that affects the runtime behaviour of the script, but it does mean the README is partly an advertising surface. Read the file itself rather than relying on the README as documentation.
On licensing, the repository listing does not state a licence. Without a licence file or a stated identifier, the default position under most copyright regimes is that no rights are granted beyond what the law allows, which makes redistribution inside a client project a question worth raising with someone qualified to answer it. This article cannot give you that answer, and the repository does not provide one either. If you need a clear licence, that absence is itself a reason to look elsewhere.
Editorial conclusion
Adopt not-paid only if you control the deployment and understand that the fade is a visible, reversible pressure tactic rather than a payment mechanism. Do not use it on a site you no longer administer, on a client who has already disputed the invoice, or anywhere a sudden visual change could be read as a security incident. Before you load the file, verify three things: that you can still push to the client's hosting, that the due_date and days_deadline values match the contract, and that you are willing to own the conversation when the client notices. The repository is small enough to read end to end, and that is the real prerequisite for using it.
Frequently asked questions
What does not-paid actually do to a client's website?
It adds opacity to the body tag and decreases it every day until the site fades away, driven by a due date and a deadline you set in the script. The README describes the effect in exactly those terms.
How do I install not-paid?
The README says to load the not-paid.js file in the head of the document. There is no package manager step, so you place the file where the site can serve it and reference it from the head.
Can I change how long the client has before the site disappears?
Yes. The README shows two variables at the top of the file, due_date and days_deadline, with a comment telling you to change them as you wish. The example uses a due date of 2017-02-27 and a deadline of 60 days.
Does not-paid accept pull requests or issue reports?
No. The README states that no pull requests or issues will be accepted for the project, so any fix you need has to live in your own copy of the file.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/kleampa-not-paid)