tina4-nodejs 3.1.1 → 3.1.2
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 +58 -48
- package/package.json +1 -1
- package/BENCHMARK_REPORT.md +0 -258
- package/CARBONAH.md +0 -140
- package/COMPARISON.md +0 -206
package/README.md
CHANGED
|
@@ -27,17 +27,22 @@
|
|
|
27
27
|
|
|
28
28
|
---
|
|
29
29
|
|
|
30
|
-
##
|
|
30
|
+
## Quick Start
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
# Install the Tina4 CLI
|
|
34
|
+
cargo install tina4 # or download binary from https://github.com/tina4stack/tina4/releases
|
|
35
|
+
|
|
36
|
+
# Create a project
|
|
37
|
+
tina4 init nodejs ./my-app
|
|
38
|
+
|
|
39
|
+
# Run it
|
|
40
|
+
cd my-app && tina4 serve
|
|
38
41
|
```
|
|
39
42
|
|
|
40
|
-
|
|
43
|
+
Open http://localhost:7148 — your app is running.
|
|
44
|
+
|
|
45
|
+
> **Alternative** (without Rust CLI): `npm install tina4-nodejs` then create `app.ts`
|
|
41
46
|
|
|
42
47
|
---
|
|
43
48
|
|
|
@@ -298,23 +303,24 @@ export default async function (request: Tina4Request, response: Tina4Response) {
|
|
|
298
303
|
}
|
|
299
304
|
|
|
300
305
|
// Programmatic: src/routes/webhooks.ts
|
|
301
|
-
import { get, post
|
|
306
|
+
import { get, post } from "tina4-nodejs";
|
|
302
307
|
|
|
303
308
|
get("/api/items", async (request, response) => {
|
|
304
309
|
response({items: []}, HTTP_OK);
|
|
305
310
|
});
|
|
306
311
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
response({ok: true}, HTTP_OK);
|
|
310
|
-
})
|
|
311
|
-
);
|
|
312
|
+
// POST routes require auth by default; GET routes are public by default.
|
|
313
|
+
// Use JSDoc @noauth / @secured annotations to override:
|
|
312
314
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
315
|
+
/** @noauth */
|
|
316
|
+
post("/api/webhook", async (request, response) => {
|
|
317
|
+
response({ok: true}, HTTP_OK);
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
/** @secured */
|
|
321
|
+
get("/api/admin/stats", async (request, response) => {
|
|
322
|
+
response({secret: true}, HTTP_OK);
|
|
323
|
+
});
|
|
318
324
|
```
|
|
319
325
|
|
|
320
326
|
Path parameter types: `{id}` (string), `[id]` (file-based), `[...slug]` (catch-all).
|
|
@@ -358,7 +364,7 @@ db.execute("INSERT INTO users (name, email) VALUES (?, ?)", ["Alice", "alice@tes
|
|
|
358
364
|
### Middleware
|
|
359
365
|
|
|
360
366
|
```typescript
|
|
361
|
-
import {
|
|
367
|
+
import { get } from "tina4-nodejs";
|
|
362
368
|
|
|
363
369
|
const authCheck = async (request: Tina4Request, response: Tina4Response, next: Function) => {
|
|
364
370
|
if (!request.headers.authorization) {
|
|
@@ -367,21 +373,18 @@ const authCheck = async (request: Tina4Request, response: Tina4Response, next: F
|
|
|
367
373
|
return next();
|
|
368
374
|
};
|
|
369
375
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
})
|
|
374
|
-
);
|
|
376
|
+
get("/protected", async (request, response) => {
|
|
377
|
+
response({secret: true}, HTTP_OK);
|
|
378
|
+
}, [authCheck]);
|
|
375
379
|
```
|
|
376
380
|
|
|
377
381
|
### JWT Authentication
|
|
378
382
|
|
|
379
383
|
```typescript
|
|
380
|
-
import {
|
|
384
|
+
import { createToken, validateToken } from "tina4-nodejs";
|
|
381
385
|
|
|
382
|
-
const
|
|
383
|
-
const
|
|
384
|
-
const payload = auth.validateToken(token);
|
|
386
|
+
const token = createToken({userId: 42}, "your-secret");
|
|
387
|
+
const payload = validateToken(token, "your-secret");
|
|
385
388
|
```
|
|
386
389
|
|
|
387
390
|
POST/PUT/PATCH/DELETE routes require `Authorization: Bearer <token>` by default. Use `noauth()` to make public, `secured()` to protect GET routes.
|
|
@@ -398,13 +401,16 @@ Backend: file (default). Set via `TINA4_SESSION_HANDLER` in `.env`.
|
|
|
398
401
|
### Queues
|
|
399
402
|
|
|
400
403
|
```typescript
|
|
401
|
-
import { Queue
|
|
404
|
+
import { Queue } from "tina4-nodejs";
|
|
402
405
|
|
|
403
|
-
|
|
406
|
+
const queue = new Queue({ topic: "emails" });
|
|
407
|
+
queue.push({ to: "alice@example.com" });
|
|
404
408
|
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
409
|
+
const job = queue.pop();
|
|
410
|
+
if (job) {
|
|
411
|
+
sendEmail(job.data);
|
|
412
|
+
job.complete();
|
|
413
|
+
}
|
|
408
414
|
```
|
|
409
415
|
|
|
410
416
|
### GraphQL
|
|
@@ -420,12 +426,14 @@ gql.registerRoute("/graphql"); // GET = GraphiQL IDE, POST = queries
|
|
|
420
426
|
### WebSocket
|
|
421
427
|
|
|
422
428
|
```typescript
|
|
423
|
-
import {
|
|
429
|
+
import { WebSocketServer } from "tina4-nodejs";
|
|
424
430
|
|
|
425
|
-
const
|
|
431
|
+
const wss = new WebSocketServer({ port: 8080 });
|
|
426
432
|
|
|
427
|
-
|
|
428
|
-
|
|
433
|
+
wss.on("connection", (client) => {
|
|
434
|
+
client.on("message", (msg) => {
|
|
435
|
+
wss.broadcast(`User said: ${msg}`);
|
|
436
|
+
});
|
|
429
437
|
});
|
|
430
438
|
```
|
|
431
439
|
|
|
@@ -489,25 +497,26 @@ const result = await api.sendRequest("/users/42");
|
|
|
489
497
|
### Data Seeder
|
|
490
498
|
|
|
491
499
|
```typescript
|
|
492
|
-
import {
|
|
500
|
+
import { FakeData } from "tina4-nodejs";
|
|
493
501
|
|
|
494
|
-
const fake = new
|
|
502
|
+
const fake = new FakeData();
|
|
495
503
|
fake.name(); // "Alice Johnson"
|
|
496
504
|
fake.email(); // "alice.johnson@example.com"
|
|
497
505
|
|
|
498
|
-
|
|
506
|
+
// Seed via ORM package:
|
|
507
|
+
// import { seedOrm } from "@tina4/orm";
|
|
508
|
+
// await seedOrm(User, 50);
|
|
499
509
|
```
|
|
500
510
|
|
|
501
511
|
### Response Cache
|
|
502
512
|
|
|
503
513
|
```typescript
|
|
504
|
-
import {
|
|
514
|
+
import { get, responseCache } from "tina4-nodejs";
|
|
505
515
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
);
|
|
516
|
+
// Apply response cache as middleware with 60-second TTL
|
|
517
|
+
get("/api/stats", async (request, response) => {
|
|
518
|
+
response(computeExpensiveStats(), HTTP_OK);
|
|
519
|
+
}, [responseCache({ ttl: 60 })]);
|
|
511
520
|
```
|
|
512
521
|
|
|
513
522
|
### SCSS, Localization
|
|
@@ -519,7 +528,7 @@ cached(60,
|
|
|
519
528
|
|
|
520
529
|
## Dev Mode
|
|
521
530
|
|
|
522
|
-
Set `
|
|
531
|
+
Set `TINA4_DEBUG=true` in `.env` to enable:
|
|
523
532
|
|
|
524
533
|
- **Live reload** -- browser auto-refreshes on code changes
|
|
525
534
|
- **CSS hot-reload** -- SCSS changes apply without page refresh
|
|
@@ -604,7 +613,8 @@ SECRET=your-jwt-secret
|
|
|
604
613
|
DATABASE_URL=sqlite:///data/app.db
|
|
605
614
|
DATABASE_USERNAME=admin # Separate credentials for networked databases
|
|
606
615
|
DATABASE_PASSWORD=secret
|
|
607
|
-
|
|
616
|
+
TINA4_DEBUG=true # Enable dev toolbar, error overlay
|
|
617
|
+
TINA4_LOG_LEVEL=ALL # ALL, DEBUG, INFO, WARNING, ERROR
|
|
608
618
|
TINA4_LANGUAGE=en # en, fr, af, zh, ja, es
|
|
609
619
|
TINA4_SESSION_HANDLER=SessionFileHandler
|
|
610
620
|
SWAGGER_TITLE=My API
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tina4-nodejs",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "This is not a framework. Tina4 for Node.js/TypeScript — zero deps, 38 built-in features.",
|
|
6
6
|
"keywords": ["tina4", "framework", "web", "api", "orm", "graphql", "websocket", "typescript"],
|
package/BENCHMARK_REPORT.md
DELETED
|
@@ -1,258 +0,0 @@
|
|
|
1
|
-
# Tina4 v3 — Comprehensive Benchmark Report
|
|
2
|
-
|
|
3
|
-
**Date:** 2026-03-21 | **Machine:** Apple M3, macOS, 16GB RAM
|
|
4
|
-
**Tool:** hey (https://github.com/rakyll/hey) | **Config:** 5000 requests, 50 concurrent, 5 runs (median)
|
|
5
|
-
**Warm-up:** 500 requests discarded before each test | **Mode:** All frameworks in production mode
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## Overall Ranking — JSON Endpoint
|
|
10
|
-
|
|
11
|
-
| # | Framework | Language | JSON req/s | List req/s | Deploy Size | Deps | Features |
|
|
12
|
-
|---|-----------|---------|:---------:|:---------:|:----------:|:----:|:--------:|
|
|
13
|
-
| 1 | Node.js raw http | Node.js | 86,662 | 24,598 | 0 KB | 0 | 1/38 |
|
|
14
|
-
| 2 | Fastify | Node.js | 79,505 | 23,395 | 2 MB | 10+ | 5/38 |
|
|
15
|
-
| 3 | Koa | Node.js | 60,400 | 23,433 | 1 MB | 5 | 3/38 |
|
|
16
|
-
| 4 | **Tina4 Node.js** | **Node.js** | **57,035** | **25,088** | **1.8 MB** | **0** | **38/38** |
|
|
17
|
-
| 5 | Express | Node.js | 56,687 | 20,720 | 2 MB | 3 | 4/38 |
|
|
18
|
-
| 6 | **Tina4 PHP** | **PHP** | **27,299** | **16,555** | **1.0 MB** | **0** | **38/38** |
|
|
19
|
-
| 7 | **Tina4 Python** | **Python** | **16,233** | **5,858** | **2.4 MB** | **0** | **38/38** |
|
|
20
|
-
| 8 | Starlette | Python | 15,978 | 7,493 | 505 KB | 4 | 6/38 |
|
|
21
|
-
| 9 | FastAPI | Python | 11,886 | 2,464 | 4.8 MB | 12+ | 8/38 |
|
|
22
|
-
| 10 | Sinatra | Ruby | 9,732 | 5,996 | 5 MB | 5 | 4/38 |
|
|
23
|
-
| 11 | **Tina4 Ruby** | **Ruby** | **9,504** | **7,648** | **892 KB** | **0** | **38/38** |
|
|
24
|
-
| 12 | Slim | PHP | 5,033 | 4,520 | 1.3 MB | 10+ | 6/38 |
|
|
25
|
-
| 13 | Flask | Python | 4,767 | 1,644 | 4.2 MB | 6 | 7/38 |
|
|
26
|
-
| 14 | Django | Python | 3,747 | 3,305 | 25 MB | 20+ | 22/38 |
|
|
27
|
-
| 15 | Symfony | PHP | 1,840 | 1,702 | 11 MB | 30+ | 8/38 |
|
|
28
|
-
| 16 | Bottle | Python | 1,251 | 676 | 200 KB | 0 | 5/38 |
|
|
29
|
-
| 17 | Laravel | PHP | 370 | 364 | 77 MB | 50+ | 25/38 |
|
|
30
|
-
|
|
31
|
-
---
|
|
32
|
-
|
|
33
|
-
## Per-Language Breakdown
|
|
34
|
-
|
|
35
|
-
### Python
|
|
36
|
-
|
|
37
|
-
| Framework | JSON req/s | List req/s | Deploy | Deps | Features | vs Tina4 |
|
|
38
|
-
|-----------|:---------:|:---------:|:------:|:----:|:--------:|:--------:|
|
|
39
|
-
| **Tina4 Python** | **16,233** | **5,858** | **2.4 MB** | **0** | **38/38** | **baseline** |
|
|
40
|
-
| Starlette | 15,978 | 7,493 | 505 KB | 4 | 6/38 | 0.98x |
|
|
41
|
-
| FastAPI | 11,886 | 2,464 | 4.8 MB | 12+ | 8/38 | 0.73x |
|
|
42
|
-
| Flask | 4,767 | 1,644 | 4.2 MB | 6 | 7/38 | 0.29x |
|
|
43
|
-
| Django | 3,747 | 3,305 | 25 MB | 20+ | 22/38 | 0.23x |
|
|
44
|
-
| Bottle | 1,251 | 676 | 200 KB | 0 | 5/38 | 0.08x |
|
|
45
|
-
|
|
46
|
-
**Tina4 Python** is #1 in Python. Matches Starlette (which uses uvicorn's C parser), 3.4x faster than Flask, 4.3x faster than Django.
|
|
47
|
-
|
|
48
|
-
### PHP
|
|
49
|
-
|
|
50
|
-
| Framework | JSON req/s | List req/s | Deploy | Deps | Features | vs Tina4 |
|
|
51
|
-
|-----------|:---------:|:---------:|:------:|:----:|:--------:|:--------:|
|
|
52
|
-
| **Tina4 PHP** | **27,299** | **16,555** | **1.0 MB** | **0** | **38/38** | **baseline** |
|
|
53
|
-
| Slim | 5,033 | 4,520 | 1.3 MB | 10+ | 6/38 | 0.18x |
|
|
54
|
-
| Symfony | 1,840 | 1,702 | 11 MB | 30+ | 8/38 | 0.07x |
|
|
55
|
-
| Laravel | 370 | 364 | 77 MB | 50+ | 25/38 | 0.01x |
|
|
56
|
-
|
|
57
|
-
**Tina4 PHP** dominates. 5.4x faster than Slim, 14.8x faster than Symfony, 73.8x faster than Laravel. 77x smaller than Laravel.
|
|
58
|
-
|
|
59
|
-
### Ruby
|
|
60
|
-
|
|
61
|
-
| Framework | JSON req/s | List req/s | Deploy | Deps | Features | vs Tina4 |
|
|
62
|
-
|-----------|:---------:|:---------:|:------:|:----:|:--------:|:--------:|
|
|
63
|
-
| Sinatra | 9,732 | 5,996 | 5 MB | 5 | 4/38 | 1.02x |
|
|
64
|
-
| **Tina4 Ruby** | **9,504** | **7,648** | **892 KB** | **0** | **38/38** | **baseline** |
|
|
65
|
-
|
|
66
|
-
**Tina4 Ruby** matches Sinatra on JSON (within noise), beats it on large payloads (7,648 vs 5,996). Ships 38 features vs 4.
|
|
67
|
-
|
|
68
|
-
### Node.js
|
|
69
|
-
|
|
70
|
-
| Framework | JSON req/s | List req/s | Deploy | Deps | Features | vs Tina4 |
|
|
71
|
-
|-----------|:---------:|:---------:|:------:|:----:|:--------:|:--------:|
|
|
72
|
-
| Node.js raw | 86,662 | 24,598 | 0 KB | 0 | 1/38 | 1.52x |
|
|
73
|
-
| Fastify | 79,505 | 23,395 | 2 MB | 10+ | 5/38 | 1.39x |
|
|
74
|
-
| Koa | 60,400 | 23,433 | 1 MB | 5 | 3/38 | 1.06x |
|
|
75
|
-
| **Tina4 Node.js** | **57,035** | **25,088** | **1.8 MB** | **0** | **38/38** | **baseline** |
|
|
76
|
-
| Express | 56,687 | 20,720 | 2 MB | 3 | 4/38 | 0.99x |
|
|
77
|
-
|
|
78
|
-
**Tina4 Node.js** beats Express (57K vs 57K), matches Koa. Fastest on large payloads (25,088 — highest of all Node.js frameworks).
|
|
79
|
-
|
|
80
|
-
---
|
|
81
|
-
|
|
82
|
-
## Deployment Size Comparison
|
|
83
|
-
|
|
84
|
-
| Framework | Size | vs Tina4 | Files |
|
|
85
|
-
|-----------|:----:|:--------:|:-----:|
|
|
86
|
-
| **Tina4 Ruby** | **892 KB** | — | ~65 |
|
|
87
|
-
| **Tina4 PHP** | **1.0 MB** | — | ~52 |
|
|
88
|
-
| **Tina4 Node.js** | **1.8 MB** | — | ~71 |
|
|
89
|
-
| **Tina4 Python** | **2.4 MB** | — | ~65 |
|
|
90
|
-
| Bottle | 200 KB | 0.08x | 1 |
|
|
91
|
-
| Starlette | 505 KB | 0.2x | ~30 |
|
|
92
|
-
| Slim | 1.3 MB | 1x | ~100 |
|
|
93
|
-
| Express | 2 MB | 1x | ~50 |
|
|
94
|
-
| Flask + deps | 4.2 MB | 2x | ~200 |
|
|
95
|
-
| FastAPI + deps | 4.8 MB | 2x | ~300 |
|
|
96
|
-
| Sinatra + deps | 5 MB | 2x | ~100 |
|
|
97
|
-
| Symfony | 11 MB | 10x | ~2000 |
|
|
98
|
-
| Django | 25 MB | 10x | ~5000 |
|
|
99
|
-
| Laravel | 77 MB | 77x | ~10000 |
|
|
100
|
-
|
|
101
|
-
---
|
|
102
|
-
|
|
103
|
-
## CO2 Emissions per 1000 Requests
|
|
104
|
-
|
|
105
|
-
Based on: 15W TDP × (1000/req_per_sec) seconds × 475g CO2/kWh grid average
|
|
106
|
-
|
|
107
|
-
| Framework | JSON req/s | Time for 1000 req | Energy (Wh) | CO2 (g) | vs Tina4 |
|
|
108
|
-
|-----------|:---------:|:----------------:|:----------:|:------:|:--------:|
|
|
109
|
-
| Node.js raw | 86,662 | 0.012s | 0.00005 | 0.023 | 0.3x |
|
|
110
|
-
| Fastify | 79,505 | 0.013s | 0.00005 | 0.025 | 0.3x |
|
|
111
|
-
| **Tina4 Node.js** | **57,035** | **0.018s** | **0.00007** | **0.035** | **baseline** |
|
|
112
|
-
| Express | 56,687 | 0.018s | 0.00007 | 0.035 | 1.0x |
|
|
113
|
-
| **Tina4 PHP** | **27,299** | **0.037s** | **0.00015** | **0.073** | **baseline** |
|
|
114
|
-
| **Tina4 Python** | **16,233** | **0.062s** | **0.00026** | **0.122** | **baseline** |
|
|
115
|
-
| Starlette | 15,978 | 0.063s | 0.00026 | 0.124 | 1.0x |
|
|
116
|
-
| FastAPI | 11,886 | 0.084s | 0.00035 | 0.167 | 1.4x |
|
|
117
|
-
| Sinatra | 9,732 | 0.103s | 0.00043 | 0.204 | 1.7x |
|
|
118
|
-
| **Tina4 Ruby** | **9,504** | **0.105s** | **0.00044** | **0.209** | **baseline** |
|
|
119
|
-
| Slim | 5,033 | 0.199s | 0.00083 | 0.394 | 5.4x |
|
|
120
|
-
| Flask | 4,767 | 0.210s | 0.00087 | 0.416 | 3.4x |
|
|
121
|
-
| Django | 3,747 | 0.267s | 0.00111 | 0.529 | 4.3x |
|
|
122
|
-
| Symfony | 1,840 | 0.543s | 0.00226 | 1.076 | 14.7x |
|
|
123
|
-
| Bottle | 1,251 | 0.799s | 0.00333 | 1.584 | 13.0x |
|
|
124
|
-
| Laravel | 370 | 2.703s | 0.01126 | 5.349 | 73.3x |
|
|
125
|
-
|
|
126
|
-
**Laravel emits 73x more CO2 per request than Tina4 PHP.**
|
|
127
|
-
|
|
128
|
-
At scale (1M requests/day):
|
|
129
|
-
- Tina4 PHP: **73g CO2/day** (26.6 kg/year)
|
|
130
|
-
- Laravel: **5,349g CO2/day** (1,952 kg/year) — **1.9 tonnes of CO2 per year more**
|
|
131
|
-
|
|
132
|
-
---
|
|
133
|
-
|
|
134
|
-
## Feature Comparison (38 features)
|
|
135
|
-
|
|
136
|
-
| Feature | Tina4 | Django | Laravel | Flask | FastAPI | Express | Sinatra | Slim | Symfony |
|
|
137
|
-
|---------|:-----:|:------:|:-------:|:-----:|:-------:|:-------:|:-------:|:----:|:-------:|
|
|
138
|
-
| **Total** | **38** | **22** | **25** | **7** | **8** | **4** | **4** | **6** | **8** |
|
|
139
|
-
| Zero deps | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
140
|
-
| ORM | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
141
|
-
| 5 DB drivers | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
142
|
-
| JWT auth | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
143
|
-
| Queue system | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
144
|
-
| WebSocket | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
145
|
-
| GraphQL | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
146
|
-
| SOAP/WSDL | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
147
|
-
| Swagger/OpenAPI | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
148
|
-
| Template engine | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ✅ |
|
|
149
|
-
| CSS framework | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
150
|
-
| Dev dashboard | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ |
|
|
151
|
-
| Gallery/examples | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
152
|
-
| AI assistant | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
153
|
-
| 4 languages | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
154
|
-
|
|
155
|
-
---
|
|
156
|
-
|
|
157
|
-
## Methodology
|
|
158
|
-
|
|
159
|
-
### How to reproduce
|
|
160
|
-
```bash
|
|
161
|
-
cd tina4-python
|
|
162
|
-
python benchmarks/benchmark.py --runs 5
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
### What we measured
|
|
166
|
-
- **JSON endpoint**: Returns `{"message": "Hello, World!", "framework": "..."}` — tests routing + JSON serialization
|
|
167
|
-
- **List endpoint**: Returns 100 items with id/name/price — tests JSON serialization of larger payloads
|
|
168
|
-
|
|
169
|
-
### Production mode
|
|
170
|
-
All frameworks run with debug/development mode OFF:
|
|
171
|
-
- Tina4: `TINA4_DEBUG=false`
|
|
172
|
-
- Flask: `FLASK_ENV=production`
|
|
173
|
-
- Django: `DEBUG=False`
|
|
174
|
-
- Laravel: `APP_DEBUG=false`
|
|
175
|
-
- Express/Fastify/Koa: `NODE_ENV=production`
|
|
176
|
-
- Sinatra: `environment=production`
|
|
177
|
-
- PHP: `display_errors=Off`
|
|
178
|
-
|
|
179
|
-
### Server types
|
|
180
|
-
- **Tina4 Python**: built-in asyncio (zero deps)
|
|
181
|
-
- **Tina4 PHP**: PHP built-in server (`php -S`)
|
|
182
|
-
- **Tina4 Ruby**: WEBrick
|
|
183
|
-
- **Tina4 Node.js**: Node.js http.createServer
|
|
184
|
-
- **Flask**: Werkzeug
|
|
185
|
-
- **Starlette/FastAPI**: uvicorn (with httptools C parser)
|
|
186
|
-
- **Django**: runserver
|
|
187
|
-
- **Laravel**: artisan serve (PHP built-in)
|
|
188
|
-
- **Symfony**: PHP built-in server
|
|
189
|
-
- **Slim**: PHP built-in server
|
|
190
|
-
- **Express/Fastify/Koa**: Node.js http
|
|
191
|
-
- **Sinatra**: Puma
|
|
192
|
-
|
|
193
|
-
### Variance
|
|
194
|
-
Individual run values are reported alongside medians. Variance of >20% between runs is flagged. The median of 5 runs provides a reliable central estimate.
|
|
195
|
-
|
|
196
|
-
### Limitations
|
|
197
|
-
- All tests use development servers (not production WSGI/ASGI servers)
|
|
198
|
-
- Production deployments with gunicorn/uvicorn/php-fpm/puma would improve all frameworks
|
|
199
|
-
- Results are specific to Apple M3 — different hardware will produce different absolute numbers
|
|
200
|
-
- Relative rankings should be consistent across hardware
|
|
201
|
-
|
|
202
|
-
---
|
|
203
|
-
|
|
204
|
-
## Cross-Platform Support
|
|
205
|
-
|
|
206
|
-
All 4 Tina4 frameworks run on:
|
|
207
|
-
- ✅ macOS (Intel + Apple Silicon)
|
|
208
|
-
- ✅ Linux (x86_64 + ARM64)
|
|
209
|
-
- ✅ Windows (10/11)
|
|
210
|
-
- ✅ Docker (any base image)
|
|
211
|
-
- ✅ WSL2
|
|
212
|
-
|
|
213
|
-
No C extensions. No native binaries. No compile step. Pure Python/PHP/Ruby/JavaScript.
|
|
214
|
-
|
|
215
|
-
---
|
|
216
|
-
|
|
217
|
-
*Generated by Tina4 Benchmark Suite v3.0.0 — https://tina4.com*
|
|
218
|
-
|
|
219
|
-
---
|
|
220
|
-
|
|
221
|
-
## Ruby — Updated Results (2026-03-21)
|
|
222
|
-
|
|
223
|
-
| Framework | JSON req/s | List req/s | Server | Deps | Features |
|
|
224
|
-
|-----------|:---------:|:---------:|--------|:----:|:--------:|
|
|
225
|
-
| Roda | 20,964 | 12,265 | Puma | 1 | 3/38 |
|
|
226
|
-
| Sinatra | 9,909 | 7,229 | Puma | 5 | 4/38 |
|
|
227
|
-
| **Tina4 Ruby** | **8,139** | **6,427** | **WEBrick** | **0** | **38/38** |
|
|
228
|
-
| Rails | 4,754 | 4,052 | Puma | 69 | 24/38 |
|
|
229
|
-
|
|
230
|
-
**Tina4 Ruby on WEBrick is 1.7x faster than Rails on Puma** — with 38 features vs 24, zero deps vs 69.
|
|
231
|
-
|
|
232
|
-
---
|
|
233
|
-
|
|
234
|
-
## Dev vs Production — Tina4 All Frameworks (2026-03-21)
|
|
235
|
-
|
|
236
|
-
| Framework | Dev Server | Dev JSON/s | Prod Server | Prod JSON/s | Prod List/s | Change |
|
|
237
|
-
|-----------|-----------|:---------:|-------------|:---------:|:---------:|:------:|
|
|
238
|
-
| **Tina4 PHP** | php -S | 27,299 | php + OPcache | **27,486** | **16,628** | ~same |
|
|
239
|
-
| **Tina4 Ruby** | WEBrick | 8,139 | Puma | **22,784** | **12,504** | **2.8x ↑** |
|
|
240
|
-
| **Tina4 Node.js** | http single | 57,035 | cluster (8 workers) | 12,488 | **16,958** | ↓ burst |
|
|
241
|
-
| **Tina4 Python** | asyncio | 16,233 | uvicorn | 9,801 | 5,221 | ↓ burst |
|
|
242
|
-
|
|
243
|
-
### Key Insights
|
|
244
|
-
|
|
245
|
-
1. **Ruby benefits most from production server** — Puma's multi-threaded C-optimized HTTP parser gives 2.8x improvement over WEBrick
|
|
246
|
-
2. **PHP is already fast** — built-in `php -S` is surprisingly competitive; OPcache helps with complex apps but not simple JSON endpoints
|
|
247
|
-
3. **Python's asyncio server is faster than uvicorn for bursts** — our hand-rolled asyncio server has less overhead than uvicorn's libuv event loop for short-lived connections
|
|
248
|
-
4. **Node.js cluster adds IPC overhead** — for burst benchmarks on a single machine, the inter-process communication cost of 8 workers outweighs the parallelism benefit
|
|
249
|
-
|
|
250
|
-
### When production servers help
|
|
251
|
-
|
|
252
|
-
Production servers excel under **sustained high concurrency** (thousands of simultaneous connections), **long-running requests** (database queries, file uploads), and **multi-core utilization** (real traffic from many clients). Burst benchmarks from a single client on localhost don't show these advantages.
|
|
253
|
-
|
|
254
|
-
### Recommendation
|
|
255
|
-
|
|
256
|
-
- `tina4 serve` — for development (toolbar, reload, gallery)
|
|
257
|
-
- `tina4 serve --production` — for deployment (auto-installs best server)
|
|
258
|
-
- Production benchmarks should use sustained load tests (wrk2, k6) not burst tests (hey, ab)
|
package/CARBONAH.md
DELETED
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
# Carbonah Green Benchmark Report
|
|
2
|
-
|
|
3
|
-
> Tina4 Node.js v3 — Test Results
|
|
4
|
-
> Date: 2026-03-21
|
|
5
|
-
> Rating: **A+**
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## Summary
|
|
10
|
-
|
|
11
|
-
| Metric | Value |
|
|
12
|
-
|--------|-------|
|
|
13
|
-
| Total Tests | 1,669 |
|
|
14
|
-
| Passed | 1,669 |
|
|
15
|
-
| Failed | 0 |
|
|
16
|
-
| Errors | 0 |
|
|
17
|
-
| Status | **PASS** |
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
## Per-Module Breakdown
|
|
22
|
-
|
|
23
|
-
| Module | Tests | Status |
|
|
24
|
-
|--------|-------|--------|
|
|
25
|
-
| Integration (end-to-end) | 37 | PASS |
|
|
26
|
-
| Smoke | 97 | PASS |
|
|
27
|
-
| Router | 30 | PASS |
|
|
28
|
-
| Auth | 45 | PASS |
|
|
29
|
-
| ORM | 28 | PASS |
|
|
30
|
-
| Database | 26 | PASS |
|
|
31
|
-
| Migration | 27 | PASS |
|
|
32
|
-
| Session | 30 | PASS |
|
|
33
|
-
| Session Handlers | 18 | PASS |
|
|
34
|
-
| Queue | 28 | PASS |
|
|
35
|
-
| Queue Backends | 20 | PASS |
|
|
36
|
-
| Swagger | 54 | PASS |
|
|
37
|
-
| WSDL | 42 | PASS |
|
|
38
|
-
| GraphQL | 36 | PASS |
|
|
39
|
-
| WebSocket | 74 | PASS |
|
|
40
|
-
| I18n | 18 | PASS |
|
|
41
|
-
| FakeData/Seeder | 51 | PASS |
|
|
42
|
-
| SCSS | 19 | PASS |
|
|
43
|
-
| Frond | 130 | PASS |
|
|
44
|
-
| Events | 39 | PASS |
|
|
45
|
-
| AI | 30 | PASS |
|
|
46
|
-
| Response | 47 | PASS |
|
|
47
|
-
| SQL Translation | 54 | PASS |
|
|
48
|
-
| HtmlElement | 24 | PASS |
|
|
49
|
-
| Form Token | 19 | PASS |
|
|
50
|
-
| Post Protection | 29 | PASS |
|
|
51
|
-
| DotEnv | 19 | PASS |
|
|
52
|
-
| CORS | 5 | PASS |
|
|
53
|
-
| Rate Limiter | 8 | PASS |
|
|
54
|
-
| Health | 6 | PASS |
|
|
55
|
-
| Log | 13 | PASS |
|
|
56
|
-
| Service Runner | 49 | PASS |
|
|
57
|
-
| Messenger | 48 | PASS |
|
|
58
|
-
| DevAdmin | 47 | PASS |
|
|
59
|
-
|
|
60
|
-
---
|
|
61
|
-
|
|
62
|
-
## Feature Parity
|
|
63
|
-
|
|
64
|
-
78/78 features implemented — 100% parity with Python, PHP, and Ruby.
|
|
65
|
-
|
|
66
|
-
| Category | Features |
|
|
67
|
-
|----------|----------|
|
|
68
|
-
| Core | Router, Middleware, CORS, Rate Limiter, Health Check, DotEnv, Logging |
|
|
69
|
-
| Database | Multi-driver abstraction, ORM, Migrations, Seeder/FakeData, SQL Translation |
|
|
70
|
-
| Auth | JWT tokens, Password hashing, API key validation, POST protection, Form tokens |
|
|
71
|
-
| API | Swagger/OpenAPI, GraphQL, WSDL/SOAP |
|
|
72
|
-
| Templates | Frond (Twig-compatible), SCSS compilation, HtmlElement builder |
|
|
73
|
-
| Communication | Queue (memory/RabbitMQ/Kafka), WebSocket, Messenger, Session (file/Redis/Mongo) |
|
|
74
|
-
| Dev Tools | Error Overlay, DevAdmin, Hot reload (via Rust CLI), AI context scaffolding |
|
|
75
|
-
| Architecture | Events (pub/sub), DI Container, Response Cache, Inline Testing, Service Runner |
|
|
76
|
-
| I18n | Localization with JSON translation files |
|
|
77
|
-
|
|
78
|
-
---
|
|
79
|
-
|
|
80
|
-
## CO2 Report
|
|
81
|
-
|
|
82
|
-
| Metric | Value |
|
|
83
|
-
|--------|-------|
|
|
84
|
-
| Test Execution Time | 18.00s |
|
|
85
|
-
| CPU Time (user+sys) | ~12s (34 separate tsx processes) |
|
|
86
|
-
| Peak Memory | ~64 MB |
|
|
87
|
-
| Platform | Apple Silicon (ARM64) |
|
|
88
|
-
| Estimated TDP | 15W |
|
|
89
|
-
| Energy per Run | 0.0000750 kWh |
|
|
90
|
-
| CO2 per Run (world avg 475g/kWh) | 0.038g CO2 |
|
|
91
|
-
| CO2 per Test | 0.000030g CO2 |
|
|
92
|
-
| Annual CI Estimate (10 runs/day) | 0.139g CO2/year |
|
|
93
|
-
| Equivalent | ~0.7m of driving a car |
|
|
94
|
-
|
|
95
|
-
### Efficiency Metrics
|
|
96
|
-
|
|
97
|
-
| Metric | Value |
|
|
98
|
-
|--------|-------|
|
|
99
|
-
| Tests per Second | 89.5 |
|
|
100
|
-
| Tests per Watt-second | 5.97 |
|
|
101
|
-
| Zero-dep Core | No unnecessary computation |
|
|
102
|
-
| Note | Higher time due to 34 separate tsx process starts; single-process would be faster |
|
|
103
|
-
|
|
104
|
-
### Carbon Comparison (per full test suite run)
|
|
105
|
-
|
|
106
|
-
| Framework | Time | CO2/Run | Tests/sec |
|
|
107
|
-
|-----------|------|---------|-----------|
|
|
108
|
-
| Python | 12.83s | 0.025g | 118.2 |
|
|
109
|
-
| PHP | 8.25s | 0.017g | 152.1 |
|
|
110
|
-
| Ruby | 6.86s | 0.014g | 221.0 |
|
|
111
|
-
| Node.js | 18.00s | 0.038g | 89.5 |
|
|
112
|
-
| **Total (6,183 tests)** | **45.94s** | **0.094g** | — |
|
|
113
|
-
|
|
114
|
-
---
|
|
115
|
-
|
|
116
|
-
## Carbonah Rating Criteria
|
|
117
|
-
|
|
118
|
-
| Criterion | Score | Notes |
|
|
119
|
-
|-----------|-------|-------|
|
|
120
|
-
| Test Coverage | 1,669 tests | All passing |
|
|
121
|
-
| Zero Dependencies | Core has no third-party deps | stdlib only |
|
|
122
|
-
| Feature Parity | 78/78 | 100% cross-framework |
|
|
123
|
-
| Code Quality | Clean, DRY, separation of concerns | Enforced via CLAUDE.md |
|
|
124
|
-
| Documentation | CLAUDE.md + plan docs | Up to date |
|
|
125
|
-
|
|
126
|
-
**Overall Rating: A+**
|
|
127
|
-
|
|
128
|
-
---
|
|
129
|
-
|
|
130
|
-
## How to Reproduce
|
|
131
|
-
|
|
132
|
-
```bash
|
|
133
|
-
cd tina4-nodejs
|
|
134
|
-
npm install
|
|
135
|
-
for f in test/*.ts; do npx tsx "$f"; done
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
---
|
|
139
|
-
|
|
140
|
-
*Generated by Tina4 v3 CI — https://tina4.com*
|
package/COMPARISON.md
DELETED
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
# Tina4 v3 — Framework Feature & Performance Report
|
|
2
|
-
|
|
3
|
-
**Date:** 2026-03-21 | **Goal:** Outperform the competition on features and close the performance gap
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Performance Benchmarks
|
|
8
|
-
|
|
9
|
-
### Python — Tina4 vs Competition
|
|
10
|
-
|
|
11
|
-
Real HTTP benchmarks — identical JSON endpoint, 5000 requests, 50 concurrent.
|
|
12
|
-
|
|
13
|
-
| Framework | JSON req/s | 100-item list req/s | Server | Deps |
|
|
14
|
-
|-----------|:---------:|:-------------------:|--------|:----:|
|
|
15
|
-
| **Tina4 Python 3.0** | **16,233** | **5,858** | **built-in** | **0** |
|
|
16
|
-
| Starlette 0.52 | 15,978 | 7,493 | uvicorn (C) | 4 |
|
|
17
|
-
| FastAPI 0.115 | 11,886 | 2,464 | uvicorn (C) | 12+ |
|
|
18
|
-
| Flask 3.1 | 4,767 | 1,644 | Werkzeug | 6 |
|
|
19
|
-
| Django 5.2 | 3,747 | 3,305 | runserver | 20+ |
|
|
20
|
-
| Bottle 0.13 | 1,251 | 676 | built-in | 0 |
|
|
21
|
-
|
|
22
|
-
### PHP — Tina4 vs Competition
|
|
23
|
-
|
|
24
|
-
Real HTTP benchmarks — identical JSON endpoint, 5000 requests, 50 concurrent.
|
|
25
|
-
|
|
26
|
-
| Framework | JSON req/s | 100-item list req/s | Server | Deps |
|
|
27
|
-
|-----------|:---------:|:-------------------:|--------|:----:|
|
|
28
|
-
| **Tina4 PHP 3.0** | **27,299** | **16,555** | **built-in** | **0** |
|
|
29
|
-
| Slim 4 | 5,033 | 4,520 | built-in | 10+ |
|
|
30
|
-
| Symfony 7 | 1,840 | 1,702 | built-in | 30+ |
|
|
31
|
-
| Laravel 11 | 370 | 364 | artisan | 50+ |
|
|
32
|
-
|
|
33
|
-
### Ruby — Tina4 vs Competition
|
|
34
|
-
|
|
35
|
-
Real HTTP benchmarks — identical JSON endpoint, 5000 requests, 50 concurrent.
|
|
36
|
-
|
|
37
|
-
| Framework | JSON req/s | 100-item list req/s | Server | Deps |
|
|
38
|
-
|-----------|:---------:|:-------------------:|--------|:----:|
|
|
39
|
-
| Roda | 20,964 | 12,265 | Puma | 1 |
|
|
40
|
-
| Sinatra | 9,909 | 7,229 | Puma | 5 |
|
|
41
|
-
| **Tina4 Ruby 3.0** | **9,504** | **7,648** | **WEBrick** | **0** |
|
|
42
|
-
| Rails 7 | 4,754 | 4,052 | Puma | 69 |
|
|
43
|
-
|
|
44
|
-
### Node.js — Tina4 vs Competition
|
|
45
|
-
|
|
46
|
-
Real HTTP benchmarks — identical JSON endpoint, 5000 requests, 50 concurrent.
|
|
47
|
-
|
|
48
|
-
| Framework | JSON req/s | 100-item list req/s | Server | Deps |
|
|
49
|
-
|-----------|:---------:|:-------------------:|--------|:----:|
|
|
50
|
-
| Node.js raw http | 86,662 | 24,598 | http | 0 |
|
|
51
|
-
| Fastify | 79,505 | 23,395 | http | 10+ |
|
|
52
|
-
| Koa | 60,400 | 23,433 | http | 5 |
|
|
53
|
-
| **Tina4 Node.js 3.0** | **57,035** | **25,088** | **http** | **0** |
|
|
54
|
-
| Express 5 | 56,687 | 20,720 | http | 3 |
|
|
55
|
-
|
|
56
|
-
### Production Server Results
|
|
57
|
-
|
|
58
|
-
| Framework | Dev Server | Dev JSON/s | Prod Server | Prod JSON/s | Change |
|
|
59
|
-
|-----------|-----------|:---------:|-------------|:---------:|:------:|
|
|
60
|
-
| **Tina4 PHP** | php -S | 27,299 | php + OPcache | **27,486** | ~same |
|
|
61
|
-
| **Tina4 Ruby** | WEBrick | 8,139 | Puma | **22,784** | **2.8x** |
|
|
62
|
-
| **Tina4 Node.js** | http single | 57,035 | cluster (8 workers) | 12,488 | see note |
|
|
63
|
-
| **Tina4 Python** | asyncio | 16,233 | uvicorn | 9,801 | see note |
|
|
64
|
-
|
|
65
|
-
Note: Production servers excel under sustained high concurrency. Burst benchmarks from localhost don't show their full advantage.
|
|
66
|
-
|
|
67
|
-
---
|
|
68
|
-
|
|
69
|
-
## Out-of-Box Feature Comparison (38 features)
|
|
70
|
-
|
|
71
|
-
✅ = ships with core install, no extra packages | ❌ = requires additional install
|
|
72
|
-
|
|
73
|
-
### Python Frameworks
|
|
74
|
-
|
|
75
|
-
| Feature | Tina4 | Flask | FastAPI | Django | Starlette | Bottle |
|
|
76
|
-
|---------|:-----:|:-----:|:-------:|:------:|:---------:|:------:|
|
|
77
|
-
| **CORE WEB** | | | | | | |
|
|
78
|
-
| Routing (decorators) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
79
|
-
| Typed path parameters | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
80
|
-
| Middleware system | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
81
|
-
| Static file serving | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
82
|
-
| CORS built-in | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ |
|
|
83
|
-
| Rate limiting | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
84
|
-
| WebSocket | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ |
|
|
85
|
-
| **DATA** | | | | | | |
|
|
86
|
-
| ORM | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ |
|
|
87
|
-
| 5 database drivers | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ |
|
|
88
|
-
| Migrations | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ |
|
|
89
|
-
| Seeder / fake data | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
90
|
-
| Sessions | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ |
|
|
91
|
-
| Response caching | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ |
|
|
92
|
-
| **AUTH** | | | | | | |
|
|
93
|
-
| JWT built-in | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
94
|
-
| Password hashing | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ |
|
|
95
|
-
| CSRF protection | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ |
|
|
96
|
-
| **FRONTEND** | | | | | | |
|
|
97
|
-
| Template engine | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ |
|
|
98
|
-
| CSS framework | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
99
|
-
| SCSS compiler | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
100
|
-
| Frontend JS helpers | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
101
|
-
| **API** | | | | | | |
|
|
102
|
-
| Swagger/OpenAPI | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ |
|
|
103
|
-
| GraphQL | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
104
|
-
| SOAP/WSDL | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
105
|
-
| HTTP client | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
106
|
-
| Queue system | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
107
|
-
| **DEV EXPERIENCE** | | | | | | |
|
|
108
|
-
| CLI scaffolding | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ |
|
|
109
|
-
| Dev admin dashboard | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ |
|
|
110
|
-
| Error overlay | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ |
|
|
111
|
-
| Live reload | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
|
|
112
|
-
| Auto-CRUD generator | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ |
|
|
113
|
-
| Gallery / examples | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
114
|
-
| AI assistant context | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
115
|
-
| Inline testing | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
116
|
-
| **ARCHITECTURE** | | | | | | |
|
|
117
|
-
| Zero dependencies | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ |
|
|
118
|
-
| Dependency injection | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ |
|
|
119
|
-
| Event system | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ |
|
|
120
|
-
| i18n / translations | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ |
|
|
121
|
-
| HTML builder | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
122
|
-
|
|
123
|
-
### Feature Count — Python
|
|
124
|
-
|
|
125
|
-
| Framework | Features | Deps | JSON req/s |
|
|
126
|
-
|-----------|:-------:|:----:|:---------:|
|
|
127
|
-
| **Tina4** | **38/38** | **0** | **16,233** |
|
|
128
|
-
| Django | 22/38 | 20+ | 3,747 |
|
|
129
|
-
| Flask | 7/38 | 6 | 4,767 |
|
|
130
|
-
| FastAPI | 8/38 | 12+ | 11,886 |
|
|
131
|
-
| Starlette | 6/38 | 4 | 15,978 |
|
|
132
|
-
| Bottle | 5/38 | 0 | 1,251 |
|
|
133
|
-
|
|
134
|
-
### Cross-Language Feature Count
|
|
135
|
-
|
|
136
|
-
| Framework | Language | Features | Deps |
|
|
137
|
-
|-----------|---------|:-------:|:----:|
|
|
138
|
-
| **Tina4** | Python/PHP/Ruby/Node.js | **38/38** | **0** |
|
|
139
|
-
| Laravel | PHP | 25/38 | 50+ |
|
|
140
|
-
| Rails | Ruby | 24/38 | 40+ |
|
|
141
|
-
| Django | Python | 22/38 | 20+ |
|
|
142
|
-
| NestJS | Node.js | 16/38 | 20+ |
|
|
143
|
-
| FastAPI | Python | 8/38 | 12+ |
|
|
144
|
-
| Flask | Python | 7/38 | 6 |
|
|
145
|
-
| Starlette | Python | 6/38 | 4 |
|
|
146
|
-
| Bottle | Python | 5/38 | 0 |
|
|
147
|
-
| Express | Node.js | 4/38 | 3 |
|
|
148
|
-
| Sinatra | Ruby | 4/38 | 5 |
|
|
149
|
-
|
|
150
|
-
---
|
|
151
|
-
|
|
152
|
-
## Tina4 Performance Roadmap
|
|
153
|
-
|
|
154
|
-
### v3.0 — Achieved
|
|
155
|
-
- [x] Pre-compile Frond templates (2.8x render improvement)
|
|
156
|
-
- [x] Production server auto-detection (uvicorn/Puma/cluster)
|
|
157
|
-
- [x] DB query caching (TINA4_DB_CACHE=true, 4x speedup)
|
|
158
|
-
- [x] ORM relationships with eager loading
|
|
159
|
-
|
|
160
|
-
### v3.1 — Next
|
|
161
|
-
- [ ] Compiled template bytecode (match Jinja2 speed)
|
|
162
|
-
- [ ] Connection pooling for database adapters
|
|
163
|
-
- [ ] HTTP/2 support in built-in server
|
|
164
|
-
- [ ] Response streaming for large payloads
|
|
165
|
-
|
|
166
|
-
### v3.2 — Future
|
|
167
|
-
- [ ] HTTP/3 (QUIC) support
|
|
168
|
-
- [ ] gRPC built-in
|
|
169
|
-
- [ ] Edge runtime support (Cloudflare Workers, Deno Deploy)
|
|
170
|
-
|
|
171
|
-
---
|
|
172
|
-
|
|
173
|
-
## Deployment Size
|
|
174
|
-
|
|
175
|
-
| Framework | Core Size | With Deps | Competitors |
|
|
176
|
-
|-----------|:---------:|:---------:|------------|
|
|
177
|
-
| Tina4 Python | ~2.4 MB | 2.4 MB (0 deps) | Django 25 MB, Flask 4.2 MB |
|
|
178
|
-
| Tina4 PHP | ~1.0 MB | 1.0 MB (0 deps) | Laravel 50+ MB, Symfony 30+ MB |
|
|
179
|
-
| Tina4 Ruby | ~892 KB | 892 KB (0 deps) | Rails 40+ MB, Sinatra 5 MB |
|
|
180
|
-
| Tina4 Node.js | ~1.8 MB | 1.8 MB (0 deps) | Express 2 MB, NestJS 20+ MB |
|
|
181
|
-
|
|
182
|
-
Zero dependencies means core size **is** deployment size. No `node_modules` bloat, no `vendor/` sprawl, no `site-packages` explosion.
|
|
183
|
-
|
|
184
|
-
---
|
|
185
|
-
|
|
186
|
-
## Cross-Platform Support
|
|
187
|
-
|
|
188
|
-
All 4 Tina4 frameworks run on:
|
|
189
|
-
|
|
190
|
-
- **macOS** (Intel + Apple Silicon)
|
|
191
|
-
- **Linux** (x86_64 + ARM64)
|
|
192
|
-
- **Windows** (10/11)
|
|
193
|
-
- **Docker** (any base image with the language runtime)
|
|
194
|
-
- **WSL2**
|
|
195
|
-
|
|
196
|
-
No C extensions, no native binaries, no compile step required. Pure Python/PHP/Ruby/JavaScript.
|
|
197
|
-
|
|
198
|
-
---
|
|
199
|
-
|
|
200
|
-
## Notes
|
|
201
|
-
|
|
202
|
-
- Performance numbers are from `hey` benchmarks (5000 requests, 50 concurrent) on Apple M3
|
|
203
|
-
- Production server results included: `tina4 serve --production` auto-installs the best server per language
|
|
204
|
-
- Tina4's competitive advantage is **features per dependency** — 38 features with 0 deps
|
|
205
|
-
- Total test suite: **6,183 tests** across all 4 languages (Python 1633, PHP 1304, Ruby 1577, Node.js 1669)
|
|
206
|
-
- The zero-dep philosophy means Tina4 works anywhere Python/PHP/Ruby/Node.js runs — no compiler needed, no native extensions, no build step
|