DEV Community

Cover image for I Wrapped My Free npm Package as a Paid REST API — Here's the Architecture
ckmtools
ckmtools

Posted on

I Wrapped My Free npm Package as a Paid REST API — Here's the Architecture

textlens is a zero-dependency npm package for text analysis — readability scoring, sentiment analysis, keyword extraction. It's free. It always will be. But I keep getting the same question: "Do you have a Python version?" Here's what I built to answer that.

The problem npm doesn't solve

Node.js packages are invisible to Python developers, Ruby developers, PHP developers, and no-code tools like Zapier and Make.

textlens pulls 177 downloads/week and has 6 GitHub stars. That sounds modest, but the point is: that entire audience is JavaScript developers. Every one of them can npm install textlens and be running in 30 seconds. Everyone else is locked out.

Python has textstat, which gives you a single Flesch reading ease score. It has nltk for tokenization. What it doesn't have is an equivalent of textlens — 8 readability formulas, sentiment analysis, keyword extraction, and SEO-relevant metrics in a single call. Ruby has even less. PHP has nearly nothing. No-code tools like Zapier have no path to npm at all.

The REST API targets everyone else.

Why not just publish a Python wrapper?

I considered it. A Python package that calls the textlens npm package under the hood via subprocess. Or a direct Python reimplementation of the same algorithms.

Both are worse than a hosted API.

A subprocess wrapper means the user needs Node.js installed — which defeats the purpose entirely. A reimplementation means maintaining two codebases that can drift apart. When I add a new readability formula to the npm package, I'd have to duplicate the work in Python (and Ruby, and Go, and whatever comes next).

A hosted API solves this once:

import requests

result = requests.post(
    "https://api.ckmtools.dev/v1/analyze",
    headers={"X-API-Key": "your_key"},
    json={"text": "Your text here..."}
)
print(result.json()["readability"]["consensus_grade"])
Enter fullscreen mode Exit fullscreen mode

One endpoint. Any HTTP client. Any language. No Node.js required.

Architecture decisions

Here's what runs where and why.

Cloudflare Workers (edge compute)

The API runs on Cloudflare Workers. The choice was between Workers, a traditional VPS, and a serverless platform like AWS Lambda.

Workers won on three criteria: sub-50ms response globally with zero cold starts, operational cost around $0.15/million requests, and — critically — they support bundling npm packages directly. The textlens package (github.com/ckmtools/textlens) gets compiled into the Worker bundle at deploy time. No separate service to maintain. No inter-service latency.

KV storage for API keys and rate limiting

Cloudflare KV stores API keys and rate limit counters. Keys are provisioned automatically via Stripe webhook: customer pays → webhook fires → key gets written to KV → customer gets their key by email.

The rate limiting is fixed-window per minute. Here's the honest trade-off: KV is eventually consistent. Two requests arriving simultaneously at different edge nodes could both "see" a counter below the limit and both succeed, briefly exceeding the rate limit. For a text analysis API, this is acceptable — it's not a financial transaction. I acknowledged this rather than pretending it doesn't exist.

Stripe for subscription management

Stripe handles the subscription lifecycle: checkout, upgrades, cancellations, failed payments. Webhooks drive key provisioning and revocation. The only manual step is the initial Stripe product/price setup.

This means I don't write payment processing code. Stripe does that. My webhook handler is about 40 lines.

Free tier: 1,000 requests/month, no credit card

The free tier exists for a real reason: developers don't commit budget to new tools without trying them. 1,000 requests is enough to build and test an integration. If you hit the limit, you know it's useful enough to pay for.

What this architecture costs to run

Cloudflare Workers requires their paid plan at $5/month for the KV namespace. That's the only standing cost. At $9/month for the Starter tier, the first subscriber covers hosting. This is not a money printer at small scale — it's a break-even tool that becomes profitable with volume.

The business model question

Wrapping a free npm package as a paid API requires honest justification.

The answer isn't "convenience" in the abstract. It's that Python/Ruby/no-code developers have no other option. The npm package has 177 downloads/week — that's real demand for text analysis tooling. The question is how many of those downloads come from developers who later discover they need the same capability in Python and hit a wall.

I don't know that number yet. That's what the waitlist is for.

17 articles about text analysis tooling later, with 359 total views on dev.to, there's clearly an audience that cares about this problem space. Whether enough of them are Python developers willing to pay $9/month is what validation answers.

What's next

The API is in development. If you work in Python, Ruby, or no-code tools and would use a hosted text analysis endpoint, the waitlist is at ckmtools.dev/api/ — free tier, no credit card.

Top comments (0)