PHPackages                             joby/smol-pow - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. joby/smol-pow

ActiveLibrary

joby/smol-pow
=============

Stateless proof of work challenge generation, solving, and verification using HMAC, SHA256 and simple nonce iteration.

016↑2712.5%PHP

Since Jul 31Pushed todayCompare

[ Source](https://github.com/joby-lol/smol-pow)[ Packagist](https://packagist.org/packages/joby/smol-pow)[ RSS](/packages/joby-smol-pow/feed)WikiDiscussions main Synced today

READMEChangelogDependenciesVersions (1)Used By (0)

smolPoW
=======

[](#smolpow)

A simple and stateless proof of work system using HMAC and designed to allow developers to drop in PoW to existing web applications with minimal friction. The main purpose is to allow an entirely static HTML/JS page to do a simple PoW and then bounce back to the specified URL.

Challenge structure
-------------------

[](#challenge-structure)

Each challenge can be passed from the server to the verification page as a single string. It is designed to be put in the URL hash, so that client-side JS can access it but it will not appear in most traffic logs.

Each challenge string is a base64-encoded JSON array with the following fields (in order):

- algorithm name (string)
- challenge nonce (random string)
- difficulty (integer)
- expiry timestamp (integer)
- return URL (string)
- HMAC signature of the above fields using the given algorithm and a server-supplied secret key (string)

Once solved, the solution can be sent back to the server to be verified by setting a cookie named `smolpow` containing the solution and the original challenge string, separated by a pipe character, and redirecting the client back to the return URL.

PoW algorithm
-------------

[](#pow-algorithm)

The proof of work algorithm itself is very simple: generate a string which, when appended to the given challenge nonce and hashed using SHA-256, results in a hash which starts with a certain number of zero bits (specified by the difficulty value). This can be done in a few different ways, but the basic idea is to try different strings until a valid one is found. Solutions are required to be at least 8 characters long but less than 32 characters long.

Implementation
--------------

[](#implementation)

To use smolPoW in your application, you need to:

1. On any page that should be inaccessible for a bot, generate a challenge according to the above format.
2. Redirect to a page on the same domain as the return URL using the challenge as a URL fragment.
3. Include smolpow.js in that page and call smolPoW.run() on page load.
4. On success, smolPoW will set a cookie containing the solution and the original challenge string, separated by a pipe character, and redirect the client back to the return URL.
5. On failure, smolPoW will display an error message and you should likely provide a way to retry. Do not redirect on failure.
6. On the target page, you must verify the solution contained in the cookie and that the challenge is valid before completing the requested action.

###  Health Score

23

—

LowBetter than 25% of packages

Maintenance65

Regular maintenance activity

Popularity8

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity11

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/f4e606aa41ebfd7d82c365c6dc4ec158fb1b0bfff5f8dcbfad4ab53e3092e6a6?d=identicon)[jobyone](/maintainers/jobyone)

---

Top Contributors

[![joby-lol](https://avatars.githubusercontent.com/u/856610?v=4)](https://github.com/joby-lol "joby-lol (3 commits)")

### Embed Badge

![Health badge](/badges/joby-smol-pow/health.svg)

```
[![Health](https://phpackages.com/badges/joby-smol-pow/health.svg)](https://phpackages.com/packages/joby-smol-pow)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
