@formata/limitr 0.5.14 β 0.5.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +112 -113
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,145 +1,144 @@
|
|
|
1
|
-
# Limitr
|
|
2
|
-
**
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
- Define plans, entitlements, and limits in a policy document β not application code
|
|
19
|
-
- Enforce limits locally and offline, embedded directly in your app
|
|
20
|
-
- Change limits without redeploying
|
|
21
|
-
- Stripe-agnostic and billing-system-agnostic
|
|
22
|
-
- Inspectable and auditable by developers and customers
|
|
23
|
-
- Event-driven enforcement (usage changes, overages, denials)
|
|
24
|
-
- Policy evolves independently from product code
|
|
25
|
-
- Built on [Stof](https://docs.stof.dev), an open-source data + logic runtime
|
|
26
|
-
|
|
27
|
-
## What Limitr Is Not
|
|
28
|
-
- Not a billing system
|
|
29
|
-
- Not a payment processor
|
|
30
|
-
- Not a hosted SaaS requirement
|
|
31
|
-
- Not a feature-flag system (outside of entitlements)
|
|
32
|
-
|
|
33
|
-
Limitr enforces **truth** about usage and limits.
|
|
34
|
-
Billing and payments can subscribe to Limitrβs events.
|
|
35
|
-
|
|
36
|
-
Limitr is designed to integrate cleanly with existing systems, not replace them.
|
|
37
|
-
|
|
38
|
-
## Why
|
|
39
|
-
Most applications implement monetization logic in files like `limits.ts`:
|
|
40
|
-
- seat limits
|
|
41
|
-
- usage caps
|
|
42
|
-
- plan checks
|
|
43
|
-
- special cases and overrides
|
|
44
|
-
|
|
45
|
-
Over time, this logic:
|
|
46
|
-
- becomes tightly coupled to the app
|
|
47
|
-
- requires redeploys to change pricing
|
|
48
|
-
- is hard to audit or explain
|
|
49
|
-
- breaks down with usage-based or AI pricing
|
|
50
|
-
|
|
51
|
-
Payments systems (like Stripe) handle money, but not **enforcement**.
|
|
52
|
-
|
|
53
|
-
Limitr separates **monetization policy** from application logic, so limits are:
|
|
54
|
-
- explicit
|
|
55
|
-
- portable
|
|
56
|
-
- testable
|
|
57
|
-
- and easy to evolve
|
|
58
|
-
|
|
59
|
-
## Who Limitr Is For
|
|
60
|
-
Limitr is a good fit if you are:
|
|
61
|
-
- Building an AI or usage-based product
|
|
62
|
-
- Implementing seat-based or credit-based pricing
|
|
63
|
-
- Shipping developer tools or infrastructure
|
|
64
|
-
- Supporting self-hosted or open-source deployments
|
|
65
|
-
- Tired of hardcoding pricing logic in application code
|
|
66
|
-
|
|
67
|
-
## Example: Seat-Based Plan Enforcement (TypeScript [JSR](https://jsr.io/@formata/limitr))
|
|
1
|
+
# Limitr
|
|
2
|
+
**Open-source policy engine for plans, limits, and usage enforcement.**
|
|
3
|
+
|
|
4
|
+
Limitr embeds monetization logic directly in your app. No hard-coded pricing, no redeploys to change limits.
|
|
5
|
+
|
|
6
|
+
## What It Does
|
|
7
|
+
Define pricing in a policy document, not application code:
|
|
8
|
+
- **Plans & entitlements** - seat limits, usage caps, feature gates
|
|
9
|
+
- **Offline enforcement** - runs locally, no API calls required
|
|
10
|
+
- **Event-driven** - react to limit hits, overages, denials
|
|
11
|
+
- **Portable** - works anywhere JavaScript runs
|
|
12
|
+
- **Inspectable** - customers and auditors can read your limits
|
|
13
|
+
|
|
14
|
+
## Why Limitr?
|
|
15
|
+
Billing systems (Stripe, etc.) handle payments. **Limitr handles enforcement.**
|
|
16
|
+
|
|
17
|
+
Most apps hardcode limits in `pricing.ts`:
|
|
68
18
|
```typescript
|
|
69
|
-
|
|
19
|
+
if (user.plan === 'free' && user.seats >= 1) {
|
|
20
|
+
throw new Error('Upgrade to add more seats');
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
This breaks down with usage-based pricing, AI products, and self-hosted deployments.
|
|
25
|
+
|
|
26
|
+
**Limitr separates policy from code** so limits are explicit, testable, and easy to evolve.
|
|
70
27
|
|
|
71
|
-
|
|
72
|
-
|
|
28
|
+
## Quick Start (Local)
|
|
29
|
+
```typescript
|
|
30
|
+
npm install @formata/limitr
|
|
31
|
+
```
|
|
32
|
+
```typescript
|
|
33
|
+
import { Limitr } from '@formata/limitr';
|
|
34
|
+
|
|
35
|
+
// Define policy (YAML, JSON, TOML, STOF) (load from DB, API, file, etc.)
|
|
73
36
|
const policy = await Limitr.new(`
|
|
74
37
|
policy:
|
|
75
38
|
credits:
|
|
76
39
|
seat:
|
|
77
|
-
description:
|
|
40
|
+
description: A single seat in our app.
|
|
78
41
|
plans:
|
|
79
42
|
free:
|
|
80
43
|
entitlements:
|
|
81
44
|
seats:
|
|
82
|
-
description: 'Each customer (user, org, etc.) with this plan can have up to this many seats.'
|
|
83
45
|
limit:
|
|
84
|
-
credit:
|
|
46
|
+
credit: seat
|
|
85
47
|
value: 1
|
|
86
48
|
increment: 1
|
|
87
|
-
|
|
49
|
+
pro:
|
|
88
50
|
entitlements:
|
|
89
51
|
seats:
|
|
90
|
-
description: 'Each customer (user, org, etc.) with this plan can have up to this many seats.'
|
|
91
52
|
limit:
|
|
92
|
-
credit:
|
|
93
|
-
value:
|
|
53
|
+
credit: seat
|
|
54
|
+
value: 10
|
|
94
55
|
increment: 1
|
|
95
56
|
`, 'yaml');
|
|
96
57
|
|
|
97
|
-
//
|
|
98
|
-
|
|
58
|
+
// Create/load customers
|
|
59
|
+
await policy.createCustomer('user_123', 'free');
|
|
60
|
+
await policy.createCustomer('user_456', 'pro');
|
|
99
61
|
|
|
100
|
-
//
|
|
101
|
-
await policy.
|
|
102
|
-
await policy.
|
|
62
|
+
// Enforce limits
|
|
63
|
+
await policy.increment('user_123', 'seats'); // true - succeeds (1/1 used)
|
|
64
|
+
await policy.increment('user_123', 'seats'); // false - fails (limit hit)
|
|
103
65
|
|
|
104
|
-
//
|
|
105
|
-
await policy.
|
|
106
|
-
|
|
66
|
+
await policy.increment('user_456', 'seats'); // true - succeeds (1/10 used)
|
|
67
|
+
await policy.allow('user_456', 'seats', 5); // true - succeeds (6/10 used)
|
|
68
|
+
```
|
|
107
69
|
|
|
108
|
-
|
|
109
|
-
policy.doc.lib('App', 'meter_limit', (json: string) => {
|
|
110
|
-
const record = JSON.parse(json);
|
|
111
|
-
if (record.customer.plan === 'free' && record.entitlement === 'seats') {
|
|
112
|
-
console.log('FREE PLAN SEAT LIMIT HIT, current: ', record.customer.meters.seats.value, ' requested: ', record.invalid_value);
|
|
113
|
-
}
|
|
114
|
-
});
|
|
70
|
+
## Common Use Cases
|
|
115
71
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
if (await policy.
|
|
119
|
-
|
|
120
|
-
|
|
72
|
+
**Seat-based plans:**
|
|
73
|
+
```typescript
|
|
74
|
+
if (await policy.increment('org_123', 'seats')) {
|
|
75
|
+
// Add user to org
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Usage-based limits:**
|
|
80
|
+
```typescript
|
|
81
|
+
if (await policy.allow('user_456', 'chat_ai_tokens', 4200)) {
|
|
82
|
+
// allowed: process LLM request
|
|
83
|
+
// usage recorded and synced in the background (*Limitr Cloud)
|
|
121
84
|
} else {
|
|
122
|
-
|
|
85
|
+
// denied: limit exceeded
|
|
123
86
|
}
|
|
124
87
|
```
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
88
|
+
|
|
89
|
+
**Feature gates:**
|
|
90
|
+
```typescript
|
|
91
|
+
const hasAdvancedFeatures = await policy.allow('user_789', 'advanced_analytics');
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Local vs Cloud
|
|
95
|
+
|
|
96
|
+
### Local (Open Source)
|
|
97
|
+
```typescript
|
|
98
|
+
const policy = await Limitr.new(policyDocument);
|
|
129
99
|
```
|
|
100
|
+
- Runs entirely in your app
|
|
101
|
+
- No external dependencies
|
|
102
|
+
- Perfect for self-hosted deployments
|
|
130
103
|
|
|
131
|
-
###
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
104
|
+
### Cloud (Fully Managed w/Stripe + UI)
|
|
105
|
+
```typescript
|
|
106
|
+
const policy = await Limitr.cloud({
|
|
107
|
+
token: 'limitr_...'
|
|
108
|
+
});
|
|
109
|
+
```
|
|
110
|
+
- Syncs policy and customer data automatically
|
|
111
|
+
- Stripe integration built-in (no Stripe dependencies in your app)
|
|
112
|
+
- UI included (pricing tables, plan selection, invoices, cancel/resume, etc)
|
|
113
|
+
- Dashboard for managing plans and customers
|
|
114
|
+
- Analytics & events (payments, revenue, margins)
|
|
115
|
+
- Create/change pricing in a couple of minutes without redeploys
|
|
116
|
+
|
|
117
|
+
[Learn more about Limitr Cloud β](https://limitr.dev)
|
|
118
|
+
|
|
119
|
+
## Documentation
|
|
120
|
+
- π [Full Documentation](https://formata.gitbook.io/limitr)
|
|
121
|
+
- π [Local Quick Start](https://formata.gitbook.io/limitr/local/quick-start)
|
|
122
|
+
- βοΈ [Cloud Quick Start](https://formata.gitbook.io/limitr/cloud/quick-start)
|
|
123
|
+
- π¬ [Discord Community](https://discord.gg/Up5kxdeXZt)
|
|
124
|
+
|
|
125
|
+
## Who It's For
|
|
126
|
+
- AI products with usage-based pricing
|
|
127
|
+
- Developer tools with seat or API limits
|
|
128
|
+
- SaaS apps that need flexible pricing
|
|
129
|
+
- Open-source projects offering paid tiers
|
|
130
|
+
- Anyone tired of hardcoding pricing logic
|
|
131
|
+
|
|
132
|
+
## Built With [Stof](https://docs.stof.dev)
|
|
133
|
+
Limitr policies are written in Stof, a data + logic language that compiles to WebAssembly. This makes policies:
|
|
134
|
+
- **Deterministic** - same input always produces same output
|
|
135
|
+
- **Portable** - runs in Node.js, browsers, Deno, Bun
|
|
136
|
+
- **Auditable** - human-readable policy documents
|
|
137
137
|
|
|
138
138
|
## License
|
|
139
|
-
Apache 2.0
|
|
139
|
+
Apache 2.0 - See [LICENSE](LICENSE)
|
|
140
140
|
|
|
141
141
|
## Contributing
|
|
142
|
-
-
|
|
143
|
-
-
|
|
144
|
-
|
|
145
|
-
> Reach out to info@stof.dev to contact us directly
|
|
142
|
+
- Issues & PRs: [GitHub](https://github.com/dev-formata-io/limitr)
|
|
143
|
+
- Questions: [Discord](https://discord.gg/Up5kxdeXZt)
|
|
144
|
+
- Contact: info@limitr.dev
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@formata/limitr",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.15",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/main.js",
|
|
6
6
|
"types": "./dist/main.d.ts",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
},
|
|
28
28
|
"homepage": "https://limitr.dev",
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@formata/stof": "^0.9.
|
|
30
|
+
"@formata/stof": "^0.9.8"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"cpy-cli": "^7.0.0",
|