9e5d1f6
commit 9e5d1f6
3 files changed
+556 -0
Showing 3 changed files+556-0
▼website/css/style.css
+382-0
| @@ -0,0 +1,382 @@ | ||
1 | +:root { | |
2 | + --bg-color: #0b0c10; | |
3 | + --text-main: #f8f8f2; | |
4 | + --text-muted: #a0a0a0; | |
5 | + --primary: #9d4edd; | |
6 | + --primary-hover: #7b2cbf; | |
7 | + --secondary: rgba(255, 255, 255, 0.1); | |
8 | + --secondary-hover: rgba(255, 255, 255, 0.2); | |
9 | + --card-bg: rgba(20, 20, 25, 0.6); | |
10 | + --glass-border: rgba(255, 255, 255, 0.08); | |
11 | +} | |
12 | + | |
13 | +* { | |
14 | + margin: 0; | |
15 | + padding: 0; | |
16 | + box-sizing: border-box; | |
17 | +} | |
18 | + | |
19 | +body { | |
20 | + font-family: 'Inter', sans-serif; | |
21 | + background-color: var(--bg-color); | |
22 | + color: var(--text-main); | |
23 | + line-height: 1.6; | |
24 | + overflow-x: hidden; | |
25 | +} | |
26 | + | |
27 | +/* Background Effects */ | |
28 | +.background-elements { | |
29 | + position: fixed; | |
30 | + top: 0; | |
31 | + left: 0; | |
32 | + width: 100vw; | |
33 | + height: 100vh; | |
34 | + z-index: -1; | |
35 | + overflow: hidden; | |
36 | +} | |
37 | + | |
38 | +.blob { | |
39 | + position: absolute; | |
40 | + filter: blur(100px); | |
41 | + opacity: 0.5; | |
42 | + border-radius: 50%; | |
43 | + animation: float 20s infinite alternate ease-in-out; | |
44 | +} | |
45 | + | |
46 | +.purple-blob { | |
47 | + width: 600px; | |
48 | + height: 600px; | |
49 | + background: radial-gradient(circle, rgba(157,78,221,0.3) 0%, rgba(0,0,0,0) 70%); | |
50 | + top: -200px; | |
51 | + right: -100px; | |
52 | +} | |
53 | + | |
54 | +.blue-blob { | |
55 | + width: 500px; | |
56 | + height: 500px; | |
57 | + background: radial-gradient(circle, rgba(67,97,238,0.2) 0%, rgba(0,0,0,0) 70%); | |
58 | + bottom: -100px; | |
59 | + left: -200px; | |
60 | + animation-delay: -5s; | |
61 | +} | |
62 | + | |
63 | +@keyframes float { | |
64 | + 0% { transform: translate(0, 0) scale(1); } | |
65 | + 100% { transform: translate(-50px, 50px) scale(1.1); } | |
66 | +} | |
67 | + | |
68 | +/* Layout */ | |
69 | +.container { | |
70 | + max-width: 1200px; | |
71 | + margin: 0 auto; | |
72 | + padding: 0 2rem; | |
73 | +} | |
74 | + | |
75 | +.section { | |
76 | + padding: 6rem 0; | |
77 | +} | |
78 | + | |
79 | +.text-center { | |
80 | + text-align: center; | |
81 | +} | |
82 | + | |
83 | +/* Typography */ | |
84 | +h1 { | |
85 | + font-size: 4.5rem; | |
86 | + font-weight: 800; | |
87 | + line-height: 1.1; | |
88 | + letter-spacing: -0.02em; | |
89 | + margin-bottom: 1.5rem; | |
90 | +} | |
91 | + | |
92 | +.text-gradient { | |
93 | + background: linear-gradient(135deg, #c77dff, #4361ee); | |
94 | + -webkit-background-clip: text; | |
95 | + -webkit-text-fill-color: transparent; | |
96 | +} | |
97 | + | |
98 | +.subtitle { | |
99 | + font-size: 1.25rem; | |
100 | + color: var(--text-muted); | |
101 | + max-width: 600px; | |
102 | + margin-bottom: 2.5rem; | |
103 | +} | |
104 | + | |
105 | +.section-title { | |
106 | + font-size: 2.5rem; | |
107 | + margin-bottom: 3rem; | |
108 | +} | |
109 | + | |
110 | +/* Navigation */ | |
111 | +.glass-nav { | |
112 | + position: fixed; | |
113 | + top: 0; | |
114 | + width: 100%; | |
115 | + background: rgba(11, 12, 16, 0.7); | |
116 | + backdrop-filter: blur(12px); | |
117 | + -webkit-backdrop-filter: blur(12px); | |
118 | + border-bottom: 1px solid var(--glass-border); | |
119 | + z-index: 100; | |
120 | +} | |
121 | + | |
122 | +.nav-content { | |
123 | + display: flex; | |
124 | + justify-content: space-between; | |
125 | + align-items: center; | |
126 | + height: 80px; | |
127 | +} | |
128 | + | |
129 | +.logo { | |
130 | + font-weight: 800; | |
131 | + font-size: 1.5rem; | |
132 | + letter-spacing: -0.05em; | |
133 | + color: #fff; | |
134 | + display: flex; | |
135 | + align-items: center; | |
136 | +} | |
137 | + | |
138 | +nav { | |
139 | + display: flex; | |
140 | + gap: 1.5rem; | |
141 | + align-items: center; | |
142 | +} | |
143 | + | |
144 | +nav a { | |
145 | + color: var(--text-muted); | |
146 | + text-decoration: none; | |
147 | + font-weight: 600; | |
148 | + transition: color 0.3s; | |
149 | +} | |
150 | + | |
151 | +nav a:hover { | |
152 | + color: #fff; | |
153 | +} | |
154 | + | |
155 | +/* Buttons */ | |
156 | +.btn { | |
157 | + display: inline-flex; | |
158 | + align-items: center; | |
159 | + justify-content: center; | |
160 | + padding: 0.6rem 1.2rem; | |
161 | + border-radius: 8px; | |
162 | + font-weight: 600; | |
163 | + text-decoration: none; | |
164 | + transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); | |
165 | + border: 1px solid transparent; | |
166 | +} | |
167 | + | |
168 | +.btn-lg { | |
169 | + padding: 1rem 2rem; | |
170 | + font-size: 1.1rem; | |
171 | +} | |
172 | + | |
173 | +.btn-primary { | |
174 | + background: var(--primary); | |
175 | + color: #fff; | |
176 | + box-shadow: 0 4px 14px 0 rgba(157, 78, 221, 0.39); | |
177 | +} | |
178 | + | |
179 | +.btn-primary:hover { | |
180 | + background: var(--primary-hover); | |
181 | + transform: translateY(-2px); | |
182 | + box-shadow: 0 6px 20px 0 rgba(157, 78, 221, 0.5); | |
183 | +} | |
184 | + | |
185 | +.btn-secondary { | |
186 | + background: var(--secondary); | |
187 | + color: #fff; | |
188 | + border: 1px solid var(--glass-border); | |
189 | +} | |
190 | + | |
191 | +.btn-secondary:hover { | |
192 | + background: var(--secondary-hover); | |
193 | + transform: translateY(-2px); | |
194 | +} | |
195 | + | |
196 | +/* Hero Section */ | |
197 | +.hero { | |
198 | + display: grid; | |
199 | + grid-template-columns: 1fr 1fr; | |
200 | + gap: 4rem; | |
201 | + align-items: center; | |
202 | + min-height: 100vh; | |
203 | + padding-top: 80px; | |
204 | +} | |
205 | + | |
206 | +.cta-group { | |
207 | + display: flex; | |
208 | + gap: 1rem; | |
209 | +} | |
210 | + | |
211 | +/* Code Window */ | |
212 | +.glass-card { | |
213 | + background: var(--card-bg); | |
214 | + border: 1px solid var(--glass-border); | |
215 | + border-radius: 16px; | |
216 | + backdrop-filter: blur(16px); | |
217 | + -webkit-backdrop-filter: blur(16px); | |
218 | + box-shadow: 0 30px 60px rgba(0, 0, 0, 0.4); | |
219 | +} | |
220 | + | |
221 | +.code-window { | |
222 | + overflow: hidden; | |
223 | +} | |
224 | + | |
225 | +.window-header { | |
226 | + background: rgba(0, 0, 0, 0.2); | |
227 | + padding: 0.75rem 1rem; | |
228 | + display: flex; | |
229 | + align-items: center; | |
230 | + gap: 8px; | |
231 | + border-bottom: 1px solid var(--glass-border); | |
232 | +} | |
233 | + | |
234 | +.dot { | |
235 | + width: 12px; | |
236 | + height: 12px; | |
237 | + border-radius: 50%; | |
238 | +} | |
239 | + | |
240 | +.dot.red { background: #ff5f56; } | |
241 | +.dot.yellow { background: #ffbd2e; } | |
242 | +.dot.green { background: #27c93f; } | |
243 | + | |
244 | +.filename { | |
245 | + margin-left: auto; | |
246 | + font-size: 0.85rem; | |
247 | + color: var(--text-muted); | |
248 | + font-family: 'Inter', sans-serif; | |
249 | +} | |
250 | + | |
251 | +pre { | |
252 | + padding: 1.5rem; | |
253 | + overflow-x: auto; | |
254 | +} | |
255 | + | |
256 | +code { | |
257 | + font-family: 'JetBrains Mono', monospace; | |
258 | + font-size: 0.95rem; | |
259 | + color: #f8f8f2; | |
260 | +} | |
261 | + | |
262 | +.keyword { color: #ff7b72; } | |
263 | +.decorator { color: #d2a8ff; } | |
264 | +.function { color: #79c0ff; } | |
265 | +.string { color: #a5d6ff; } | |
266 | + | |
267 | +/* Features Grid */ | |
268 | +.features-grid { | |
269 | + display: grid; | |
270 | + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); | |
271 | + gap: 2rem; | |
272 | +} | |
273 | + | |
274 | +.feature-card { | |
275 | + padding: 2rem; | |
276 | + transition: transform 0.3s, box-shadow 0.3s; | |
277 | +} | |
278 | + | |
279 | +.hover-lift:hover { | |
280 | + transform: translateY(-5px); | |
281 | + box-shadow: 0 20px 40px rgba(0,0,0,0.4), inset 0 0 0 1px rgba(255,255,255,0.1); | |
282 | +} | |
283 | + | |
284 | +.feature-icon { | |
285 | + margin-bottom: 1rem; | |
286 | +} | |
287 | + | |
288 | +.feature-card h3 { | |
289 | + margin-bottom: 0.75rem; | |
290 | + font-size: 1.25rem; | |
291 | +} | |
292 | + | |
293 | +.feature-card p { | |
294 | + color: var(--text-muted); | |
295 | + font-size: 0.95rem; | |
296 | +} | |
297 | + | |
298 | +/* Benchmark Table */ | |
299 | +.matrix-container { | |
300 | + overflow-x: auto; | |
301 | + padding: 1rem; | |
302 | +} | |
303 | + | |
304 | +.benchmark-table { | |
305 | + width: 100%; | |
306 | + border-collapse: collapse; | |
307 | + text-align: left; | |
308 | +} | |
309 | + | |
310 | +.benchmark-table th, .benchmark-table td { | |
311 | + padding: 1.2rem; | |
312 | + border-bottom: 1px solid var(--glass-border); | |
313 | +} | |
314 | + | |
315 | +.benchmark-table th { | |
316 | + font-weight: 600; | |
317 | + color: var(--text-muted); | |
318 | + text-transform: uppercase; | |
319 | + font-size: 0.85rem; | |
320 | + letter-spacing: 0.05em; | |
321 | +} | |
322 | + | |
323 | +.benchmark-table tbody tr:last-child td { | |
324 | + border-bottom: none; | |
325 | +} | |
326 | + | |
327 | +.benchmark-table .highlight { | |
328 | + color: #fff; | |
329 | + font-weight: 600; | |
330 | +} | |
331 | + | |
332 | +.benchmark-table .success { | |
333 | + color: #27c93f; | |
334 | + font-weight: 600; | |
335 | +} | |
336 | + | |
337 | +/* Animations */ | |
338 | +.animate-up { | |
339 | + opacity: 0; | |
340 | + transform: translateY(30px); | |
341 | + animation: fadeUp 0.8s cubic-bezier(0.16, 1, 0.3, 1) forwards; | |
342 | +} | |
343 | + | |
344 | +.delay-1 { animation-delay: 0.2s; } | |
345 | +.delay-2 { animation-delay: 0.4s; } | |
346 | +.delay-3 { animation-delay: 0.6s; } | |
347 | + | |
348 | +@keyframes fadeUp { | |
349 | + to { | |
350 | + opacity: 1; | |
351 | + transform: translateY(0); | |
352 | + } | |
353 | +} | |
354 | + | |
355 | +/* Responsive */ | |
356 | +@media (max-width: 992px) { | |
357 | + .hero { | |
358 | + grid-template-columns: 1fr; | |
359 | + text-align: center; | |
360 | + padding-top: 120px; | |
361 | + } | |
362 | + | |
363 | + .subtitle { | |
364 | + margin: 0 auto 2.5rem; | |
365 | + } | |
366 | + | |
367 | + .cta-group { | |
368 | + justify-content: center; | |
369 | + } | |
370 | + | |
371 | + h1 { | |
372 | + font-size: 3.5rem; | |
373 | + } | |
374 | +} | |
375 | + | |
376 | +footer { | |
377 | + padding: 2rem 0; | |
378 | + border-top: 1px solid var(--glass-border); | |
379 | + margin-top: 4rem; | |
380 | + color: var(--text-muted); | |
381 | + font-size: 0.9rem; | |
382 | +} | |
0 | 383 | |
▼website/index.html
+161-0
| @@ -0,0 +1,161 @@ | ||
1 | +<!DOCTYPE html> | |
2 | +<html lang="en"> | |
3 | +<head> | |
4 | + <meta charset="UTF-8"> | |
5 | + <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
6 | + <title>JustAPI - High-Performance Python Web Framework</title> | |
7 | + <meta name="description" content="A drop-in replacement for FastAPI backed by Rust. Achieve up to 324k RPS effortlessly."> | |
8 | + <link rel="stylesheet" href="css/style.css"> | |
9 | + <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;800&family=JetBrains+Mono:wght@400;700&display=swap" rel="stylesheet"> | |
10 | +</head> | |
11 | +<body> | |
12 | + <div class="background-elements"> | |
13 | + <div class="blob purple-blob"></div> | |
14 | + <div class="blob blue-blob"></div> | |
15 | + </div> | |
16 | + | |
17 | + <header class="glass-nav"> | |
18 | + <div class="container nav-content"> | |
19 | + <div class="logo"> | |
20 | + <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align: middle; margin-right: 8px;"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"></polygon></svg> | |
21 | + JustAPI | |
22 | + </div> | |
23 | + <nav> | |
24 | + <a href="#features">Features</a> | |
25 | + <a href="#benchmarks">Benchmarks</a> | |
26 | + <a href="https://justapi.dev/docs" class="btn btn-secondary">Documentation</a> | |
27 | + <a href="https://github.com/justapi/justapi" class="btn btn-primary">GitHub</a> | |
28 | + </nav> | |
29 | + </div> | |
30 | + </header> | |
31 | + | |
32 | + <main> | |
33 | + <section class="hero container"> | |
34 | + <div class="hero-text"> | |
35 | + <h1 class="animate-up">The speed of <span class="text-gradient">Rust</span>.<br>The elegance of <span class="text-gradient">Python</span>.</h1> | |
36 | + <p class="subtitle animate-up delay-1">JustAPI is a drop-in replacement for FastAPI engineered for extreme throughput. Achieve up to 9x the throughput and 22x lower tail latency.</p> | |
37 | + <div class="cta-group animate-up delay-2"> | |
38 | + <a href="https://justapi.dev/docs/getting_started" class="btn btn-primary btn-lg"> | |
39 | + <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-right: 8px; vertical-align: middle;"><path d="M5 12h14M12 5l7 7-7 7"/></svg> | |
40 | + Get Started | |
41 | + </a> | |
42 | + <a href="#benchmarks" class="btn btn-secondary btn-lg">View Benchmarks</a> | |
43 | + </div> | |
44 | + </div> | |
45 | + <div class="hero-visual animate-up delay-3"> | |
46 | + <div class="code-window glass-card"> | |
47 | + <div class="window-header"> | |
48 | + <span class="dot red"></span> | |
49 | + <span class="dot yellow"></span> | |
50 | + <span class="dot green"></span> | |
51 | + <span class="filename">main.py</span> | |
52 | + </div> | |
53 | + <pre><code><span class="keyword">from</span> justapi <span class="keyword">import</span> JustAPIApp | |
54 | + | |
55 | +app = JustAPIApp() | |
56 | + | |
57 | +<span class="decorator">@app.get</span>(<span class="string">"/"</span>) | |
58 | +<span class="keyword">async def</span> <span class="function">hello</span>(): | |
59 | + <span class="keyword">return</span> {<span class="string">"message"</span>: <span class="string">"324k RPS, easily."</span>} | |
60 | + | |
61 | +<span class="keyword">if</span> __name__ == <span class="string">"__main__"</span>: | |
62 | + app.run(<span class="string">"127.0.0.1:8000"</span>)</code></pre> | |
63 | + </div> | |
64 | + </div> | |
65 | + </section> | |
66 | + | |
67 | + <section id="features" class="container section"> | |
68 | + <h2 class="section-title text-center">Why JustAPI?</h2> | |
69 | + <div class="features-grid"> | |
70 | + <div class="feature-card glass-card hover-lift"> | |
71 | + <div class="feature-icon"> | |
72 | + <svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="url(#gradient-primary)" stroke-width="1.5"><rect x="2" y="3" width="20" height="14" rx="2" ry="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></svg> | |
73 | + </div> | |
74 | + <h3>Rust Core</h3> | |
75 | + <p>The entire HTTP server, routing, and protocol parsing is written in Rust using Tokio and Hyper.</p> | |
76 | + </div> | |
77 | + <div class="feature-card glass-card hover-lift"> | |
78 | + <div class="feature-icon"> | |
79 | + <svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="url(#gradient-primary)" stroke-width="1.5"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/><polyline points="14 2 14 8 20 8"/><path d="M9 15l2 2 4-4"/></svg> | |
80 | + </div> | |
81 | + <h3>Python Ergonomics</h3> | |
82 | + <p>Write standard Python using familiar concepts. It's designed as a drop-in replacement for FastAPI.</p> | |
83 | + </div> | |
84 | + <div class="feature-card glass-card hover-lift"> | |
85 | + <div class="feature-icon"> | |
86 | + <svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="url(#gradient-primary)" stroke-width="1.5"><polygon points="12 2 2 7 12 12 22 7 12 2"/><polyline points="2 17 12 22 22 17"/><polyline points="2 12 12 17 22 12"/></svg> | |
87 | + </div> | |
88 | + <h3>Zero-Copy</h3> | |
89 | + <p>Avoids unnecessary allocations between Rust and Python, making it incredibly memory-efficient.</p> | |
90 | + </div> | |
91 | + <div class="feature-card glass-card hover-lift"> | |
92 | + <div class="feature-icon"> | |
93 | + <svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="url(#gradient-primary)" stroke-width="1.5"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg> | |
94 | + </div> | |
95 | + <h3>100% Async</h3> | |
96 | + <p>Exposes native Python asyncio boundaries tightly integrated with the underlying Rust event loop.</p> | |
97 | + </div> | |
98 | + </div> | |
99 | + </section> | |
100 | + | |
101 | + <section id="benchmarks" class="container section"> | |
102 | + <h2 class="section-title text-center">Performance Matrix</h2> | |
103 | + <p class="text-center subtitle" style="margin: 0 auto 3rem;">JustAPI crushes traditional frameworks under load. Measured on an Intel Core i5-13600K.</p> | |
104 | + | |
105 | + <div class="matrix-container glass-card"> | |
106 | + <table class="benchmark-table"> | |
107 | + <thead> | |
108 | + <tr> | |
109 | + <th>Metric / Workload</th> | |
110 | + <th>Uvicorn + FastAPI</th> | |
111 | + <th>JustAPI (Native Python)</th> | |
112 | + <th>Improvement</th> | |
113 | + </tr> | |
114 | + </thead> | |
115 | + <tbody> | |
116 | + <tr> | |
117 | + <td><strong>Hello-World (GET)</strong> - Throughput</td> | |
118 | + <td>36,189 req/sec</td> | |
119 | + <td class="highlight">324,130 req/sec</td> | |
120 | + <td class="success">~9.0x Faster</td> | |
121 | + </tr> | |
122 | + <tr> | |
123 | + <td><strong>Hello-World (GET)</strong> - p99 Latency</td> | |
124 | + <td>24.63 ms</td> | |
125 | + <td class="highlight">1.10 ms</td> | |
126 | + <td class="success">~22.4x Lower</td> | |
127 | + </tr> | |
128 | + <tr> | |
129 | + <td><strong>JSON-Echo (POST)</strong> - Throughput</td> | |
130 | + <td>26,000 req/sec</td> | |
131 | + <td class="highlight">267,846 req/sec</td> | |
132 | + <td class="success">~10.3x Faster</td> | |
133 | + </tr> | |
134 | + <tr> | |
135 | + <td><strong>JSON-Echo (POST)</strong> - p99 Latency</td> | |
136 | + <td>14.50 ms</td> | |
137 | + <td class="highlight">1.64 ms</td> | |
138 | + <td class="success">~8.8x Lower</td> | |
139 | + </tr> | |
140 | + </tbody> | |
141 | + </table> | |
142 | + </div> | |
143 | + </section> | |
144 | + | |
145 | + <svg style="width:0;height:0;position:absolute;" aria-hidden="true" focusable="false"> | |
146 | + <linearGradient id="gradient-primary" x1="0%" y1="0%" x2="100%" y2="100%"> | |
147 | + <stop offset="0%" stop-color="#c77dff" /> | |
148 | + <stop offset="100%" stop-color="#4361ee" /> | |
149 | + </linearGradient> | |
150 | + </svg> | |
151 | + </main> | |
152 | + | |
153 | + <footer> | |
154 | + <div class="container text-center"> | |
155 | + <p>© 2026 JustAPI Contributors. Released under the MIT License.</p> | |
156 | + </div> | |
157 | + </footer> | |
158 | + | |
159 | + <script src="js/main.js"></script> | |
160 | +</body> | |
161 | +</html> | |
0 | 162 | |
▼website/js/main.js
+13-0
| @@ -0,0 +1,13 @@ | ||
1 | +document.addEventListener('DOMContentLoaded', () => { | |
2 | + // Add subtle parallax to background blobs | |
3 | + document.addEventListener('mousemove', (e) => { | |
4 | + const x = e.clientX / window.innerWidth; | |
5 | + const y = e.clientY / window.innerHeight; | |
6 | + | |
7 | + const blobs = document.querySelectorAll('.blob'); | |
8 | + blobs.forEach((blob, index) => { | |
9 | + const factor = index === 0 ? 30 : -30; | |
10 | + blob.style.transform = `translate(${x * factor}px, ${y * factor}px)`; | |
11 | + }); | |
12 | + }); | |
13 | +}); | |
0 | 14 | |