create-aziz-app 2.0.11 → 2.0.13

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.
@@ -0,0 +1,473 @@
1
+ # Next.js Comparison
2
+
3
+ ## Overview
4
+
5
+ Aziz App is a **lightweight Next.js clone** with all the core benefits but zero dependencies and minimal complexity.
6
+
7
+ ## Feature Comparison
8
+
9
+ | Feature | Aziz App | Next.js | Notes |
10
+ |---------|----------|---------|-------|
11
+ | **React Hooks** | ✅ | ✅ | useState, useEffect, useMemo, useCallback, useRef, useReducer |
12
+ | **File-based Routing** | ✅ | ✅ | pages/ folder → routes |
13
+ | **API Routes** | ✅ | ✅ | api/ folder → endpoints |
14
+ | **Server-side API** | ✅ | ✅ | Real Node.js backend |
15
+ | **Hot Reload** | ✅ | ✅ | WebSocket-based |
16
+ | **Auto Import** | ✅ | ✅ | No manual imports needed |
17
+ | **Zero Config** | ✅ | ❌ | No config files needed |
18
+ | **Bundle Size** | **~50KB** | ~300KB+ | 6x smaller! |
19
+ | **Dependencies** | **0** | 20+ | No node_modules bloat |
20
+ | **Build Time** | **Instant** | Slow | No build step |
21
+ | **SSR** | ❌ | ✅ | Client-side only |
22
+ | **SSG** | ❌ | ✅ | Client-side only |
23
+ | **Image Optimization** | ❌ | ✅ | Use CDN instead |
24
+ | **TypeScript** | ❌ | ✅ | Pure JavaScript |
25
+ | **Middleware** | ❌ | ✅ | Keep it simple |
26
+
27
+ ## React Hooks - Identical API
28
+
29
+ ### useState
30
+
31
+ ```javascript
32
+ // Next.js
33
+ import { useState } from 'react';
34
+ const [count, setCount] = useState(0);
35
+
36
+ // Aziz App - EXACTLY THE SAME!
37
+ const [count, setCount] = useState(0);
38
+ ```
39
+
40
+ ### useEffect
41
+
42
+ ```javascript
43
+ // Next.js
44
+ import { useEffect } from 'react';
45
+ useEffect(() => {
46
+ console.log('Mounted!');
47
+ return () => console.log('Cleanup!');
48
+ }, [dependency]);
49
+
50
+ // Aziz App - EXACTLY THE SAME!
51
+ useEffect(() => {
52
+ console.log('Mounted!');
53
+ return () => console.log('Cleanup!');
54
+ }, [dependency]);
55
+ ```
56
+
57
+ ### useMemo
58
+
59
+ ```javascript
60
+ // Next.js
61
+ import { useMemo } from 'react';
62
+ const value = useMemo(() => expensiveCalc(), [dep]);
63
+
64
+ // Aziz App - EXACTLY THE SAME!
65
+ const value = useMemo(() => expensiveCalc(), [dep]);
66
+ ```
67
+
68
+ ### useCallback
69
+
70
+ ```javascript
71
+ // Next.js
72
+ import { useCallback } from 'react';
73
+ const callback = useCallback(() => doSomething(), [dep]);
74
+
75
+ // Aziz App - EXACTLY THE SAME!
76
+ const callback = useCallback(() => doSomething(), [dep]);
77
+ ```
78
+
79
+ ### useRef
80
+
81
+ ```javascript
82
+ // Next.js
83
+ import { useRef } from 'react';
84
+ const ref = useRef(null);
85
+
86
+ // Aziz App - EXACTLY THE SAME!
87
+ const ref = useRef(null);
88
+ ```
89
+
90
+ ### useReducer
91
+
92
+ ```javascript
93
+ // Next.js
94
+ import { useReducer } from 'react';
95
+ const [state, dispatch] = useReducer(reducer, initialState);
96
+
97
+ // Aziz App - EXACTLY THE SAME!
98
+ const [state, dispatch] = useReducer(reducer, initialState);
99
+ ```
100
+
101
+ ## API Routes - Identical API
102
+
103
+ ### Basic Route
104
+
105
+ ```javascript
106
+ // Next.js (pages/api/hello.js)
107
+ export default async function handler(req, res) {
108
+ res.status(200).json({ message: 'Hello' });
109
+ }
110
+
111
+ // Aziz App (api/hello.js) - EXACTLY THE SAME!
112
+ export default async function handler(req, res) {
113
+ res.status(200).json({ message: 'Hello' });
114
+ }
115
+ ```
116
+
117
+ ### Request Object
118
+
119
+ ```javascript
120
+ // Both Next.js and Aziz App
121
+ {
122
+ method: 'GET' | 'POST' | 'PUT' | 'DELETE',
123
+ body: {}, // Parsed JSON
124
+ query: {}, // URL parameters
125
+ headers: {}, // Request headers
126
+ url: string // Full URL
127
+ }
128
+ ```
129
+
130
+ ### Response Methods
131
+
132
+ ```javascript
133
+ // Both Next.js and Aziz App
134
+ res.status(200) // Set status
135
+ res.json({ data: 'value' }) // Send JSON
136
+ res.send('text') // Send text
137
+ res.setHeader('X-Custom', 'value') // Set header
138
+ ```
139
+
140
+ ### CRUD Example
141
+
142
+ ```javascript
143
+ // Works identically in both!
144
+ export default async function handler(req, res) {
145
+ switch (req.method) {
146
+ case 'GET':
147
+ return res.status(200).json({ users: [] });
148
+ case 'POST':
149
+ return res.status(201).json({ created: true });
150
+ case 'PUT':
151
+ return res.status(200).json({ updated: true });
152
+ case 'DELETE':
153
+ return res.status(200).json({ deleted: true });
154
+ default:
155
+ return res.status(405).json({ error: 'Method not allowed' });
156
+ }
157
+ }
158
+ ```
159
+
160
+ ## File-based Routing
161
+
162
+ ### Pages
163
+
164
+ ```
165
+ // Next.js
166
+ pages/
167
+ ├── index.js → /
168
+ ├── about.js → /about
169
+ └── contact.js → /contact
170
+
171
+ // Aziz App - Same concept!
172
+ pages/
173
+ ├── Home.jsx → #/home
174
+ ├── About.jsx → #/about
175
+ └── Contact.jsx → #/contact
176
+ ```
177
+
178
+ ### Auto-Registration
179
+
180
+ ```javascript
181
+ // Next.js - Automatic
182
+ // Just create the file
183
+
184
+ // Aziz App - Automatic too!
185
+ // Just name your function: AboutPage()
186
+ function AboutPage() {
187
+ return <div><h1>About</h1></div>;
188
+ }
189
+ ```
190
+
191
+ ## Data Fetching
192
+
193
+ ### Client-side Fetching
194
+
195
+ ```javascript
196
+ // Next.js
197
+ import { useState, useEffect } from 'react';
198
+
199
+ function Page() {
200
+ const [data, setData] = useState(null);
201
+
202
+ useEffect(() => {
203
+ fetch('/api/users')
204
+ .then(res => res.json())
205
+ .then(setData);
206
+ }, []);
207
+
208
+ return <div>{data?.message}</div>;
209
+ }
210
+
211
+ // Aziz App - EXACTLY THE SAME!
212
+ function Page() {
213
+ const [data, setData] = useState(null);
214
+
215
+ useEffect(() => {
216
+ fetch('/api/users')
217
+ .then(res => res.json())
218
+ .then(setData);
219
+ }, []);
220
+
221
+ return <div>{data?.message}</div>;
222
+ }
223
+ ```
224
+
225
+ ### Custom Hook
226
+
227
+ ```javascript
228
+ // Both Next.js and Aziz App
229
+ function useFetch(url) {
230
+ const [data, setData] = useState(null);
231
+ const [loading, setLoading] = useState(true);
232
+
233
+ useEffect(() => {
234
+ fetch(url)
235
+ .then(res => res.json())
236
+ .then(data => {
237
+ setData(data);
238
+ setLoading(false);
239
+ });
240
+ }, [url]);
241
+
242
+ return { data, loading };
243
+ }
244
+ ```
245
+
246
+ ## JSX Syntax
247
+
248
+ ### Components
249
+
250
+ ```jsx
251
+ // Next.js
252
+ export default function Button({ onClick, children }) {
253
+ return <button onClick={onClick}>{children}</button>;
254
+ }
255
+
256
+ // Aziz App - Same JSX!
257
+ function Button({ onClick, children }) {
258
+ return <button onClick={onClick}>{children}</button>;
259
+ }
260
+ ```
261
+
262
+ ### Props
263
+
264
+ ```jsx
265
+ // Both support the same props
266
+ <div
267
+ class="container"
268
+ style={{ color: 'red' }}
269
+ onClick={() => alert('Hi')}
270
+ >
271
+ Content
272
+ </div>
273
+ ```
274
+
275
+ ## Development Experience
276
+
277
+ ### Hot Reload
278
+
279
+ ```
280
+ // Next.js
281
+ 1. Save file
282
+ 2. Fast Refresh
283
+ 3. State preserved
284
+
285
+ // Aziz App
286
+ 1. Save file
287
+ 2. WebSocket reload
288
+ 3. Full page reload (state reset)
289
+ ```
290
+
291
+ ### Error Messages
292
+
293
+ ```
294
+ // Next.js
295
+ - Detailed error overlay
296
+ - Stack traces
297
+ - Suggestions
298
+
299
+ // Aziz App
300
+ - Browser console errors
301
+ - Simpler debugging
302
+ - Less magic
303
+ ```
304
+
305
+ ## When to Use Each
306
+
307
+ ### Use Aziz App When:
308
+
309
+ ✅ Building simple SPAs
310
+ ✅ Learning React concepts
311
+ ✅ Prototyping quickly
312
+ ✅ Want zero dependencies
313
+ ✅ Don't need SSR/SSG
314
+ ✅ Want instant startup
315
+ ✅ Prefer simplicity
316
+
317
+ ### Use Next.js When:
318
+
319
+ ✅ Need SEO (SSR/SSG)
320
+ ✅ Building large apps
321
+ ✅ Need image optimization
322
+ ✅ Want TypeScript
323
+ ✅ Need middleware
324
+ ✅ Want edge functions
325
+ ✅ Building production apps
326
+
327
+ ## Migration Path
328
+
329
+ ### From Aziz App to Next.js
330
+
331
+ 1. **Pages** - Rename files, adjust exports
332
+ 2. **API Routes** - Copy as-is (same API!)
333
+ 3. **Hooks** - No changes needed (same API!)
334
+ 4. **Components** - Minor adjustments
335
+ 5. **Styling** - Add CSS modules if needed
336
+
337
+ ### From Next.js to Aziz App
338
+
339
+ 1. **Remove SSR/SSG** - Convert to client-side
340
+ 2. **Pages** - Adjust file names
341
+ 3. **API Routes** - Copy as-is (same API!)
342
+ 4. **Hooks** - No changes needed (same API!)
343
+ 5. **Remove dependencies** - Delete node_modules
344
+
345
+ ## Performance
346
+
347
+ ### Bundle Size
348
+
349
+ ```
350
+ Next.js Production Build:
351
+ - Framework: ~300KB
352
+ - Runtime: ~100KB
353
+ - Total: ~400KB+
354
+
355
+ Aziz App:
356
+ - Framework: ~50KB
357
+ - Runtime: 0KB (browser native)
358
+ - Total: ~50KB
359
+ ```
360
+
361
+ ### Startup Time
362
+
363
+ ```
364
+ Next.js:
365
+ - npm install: 2-5 minutes
366
+ - npm run dev: 10-30 seconds
367
+ - First load: 2-5 seconds
368
+
369
+ Aziz App:
370
+ - npm install: 5 seconds
371
+ - npm run dev: <1 second
372
+ - First load: <1 second
373
+ ```
374
+
375
+ ### Build Time
376
+
377
+ ```
378
+ Next.js:
379
+ - Development: 10-30 seconds
380
+ - Production: 1-5 minutes
381
+
382
+ Aziz App:
383
+ - Development: Instant
384
+ - Production: No build needed
385
+ ```
386
+
387
+ ## Code Examples
388
+
389
+ ### Counter Component
390
+
391
+ ```jsx
392
+ // Works identically in both!
393
+ function Counter() {
394
+ const [count, setCount] = useState(0);
395
+
396
+ return (
397
+ <div>
398
+ <p>Count: {count}</p>
399
+ <button onClick={() => setCount(count + 1)}>
400
+ Increment
401
+ </button>
402
+ </div>
403
+ );
404
+ }
405
+ ```
406
+
407
+ ### Form with Validation
408
+
409
+ ```jsx
410
+ // Works identically in both!
411
+ function ContactForm() {
412
+ const [name, setName] = useState('');
413
+ const [email, setEmail] = useState('');
414
+ const [error, setError] = useState('');
415
+
416
+ const handleSubmit = async (e) => {
417
+ e.preventDefault();
418
+
419
+ if (!name || !email) {
420
+ setError('All fields required');
421
+ return;
422
+ }
423
+
424
+ const res = await fetch('/api/contact', {
425
+ method: 'POST',
426
+ headers: { 'Content-Type': 'application/json' },
427
+ body: JSON.stringify({ name, email })
428
+ });
429
+
430
+ if (res.ok) {
431
+ alert('Sent!');
432
+ }
433
+ };
434
+
435
+ return (
436
+ <form onSubmit={handleSubmit}>
437
+ <input
438
+ value={name}
439
+ onChange={(e) => setName(e.target.value)}
440
+ placeholder="Name"
441
+ />
442
+ <input
443
+ value={email}
444
+ onChange={(e) => setEmail(e.target.value)}
445
+ placeholder="Email"
446
+ />
447
+ {error && <p>{error}</p>}
448
+ <button type="submit">Submit</button>
449
+ </form>
450
+ );
451
+ }
452
+ ```
453
+
454
+ ## Summary
455
+
456
+ Aziz App is a **lightweight Next.js clone** that provides:
457
+
458
+ - ✅ **Same React Hooks API** - useState, useEffect, etc.
459
+ - ✅ **Same API Routes** - Identical req/res objects
460
+ - ✅ **Same JSX Syntax** - Write components the same way
461
+ - ✅ **Same Development Flow** - File-based routing, hot reload
462
+ - ✅ **Zero Dependencies** - No node_modules bloat
463
+ - ✅ **Instant Startup** - No build step
464
+ - ✅ **6x Smaller** - Minimal bundle size
465
+
466
+ Perfect for:
467
+ - 🎓 Learning React/Next.js concepts
468
+ - 🚀 Rapid prototyping
469
+ - 📱 Simple SPAs
470
+ - 🎨 Portfolio sites
471
+ - 🧪 Experiments
472
+
473
+ **It's Next.js, but lightweight!** 🎉
@@ -1,96 +1,12 @@
1
1
  /** @jsx h */
2
2
 
3
3
  // ============================================================
4
- // API ROUTE SYSTEM
5
- // Next.js-like API routes for client-side
6
- // Can be easily replaced with real backend calls
4
+ // API CLIENT
5
+ // Fetch-like API for making requests to backend API routes
6
+ // API routes run on the SERVER (Node.js), not in the browser
7
7
  // ============================================================
8
8
 
9
- // API routes registry
10
- const apiRoutes = {};
11
-
12
- // Register an API route
13
- function registerApiRoute(path, handler) {
14
- apiRoutes[path] = handler;
15
- console.log(`Registered API route: /api/${path}`);
16
- }
17
-
18
- // API request/response helpers
19
- class ApiRequest {
20
- constructor(method, body, query, params) {
21
- this.method = method;
22
- this.body = body;
23
- this.query = query;
24
- this.params = params;
25
- }
26
- }
27
-
28
- class ApiResponse {
29
- constructor() {
30
- this.statusCode = 200;
31
- this.headers = {};
32
- this.data = null;
33
- }
34
-
35
- status(code) {
36
- this.statusCode = code;
37
- return this;
38
- }
39
-
40
- json(data) {
41
- this.data = data;
42
- this.headers['Content-Type'] = 'application/json';
43
- return this;
44
- }
45
-
46
- send(data) {
47
- this.data = data;
48
- return this;
49
- }
50
- }
51
-
52
- // Execute an API route
53
- async function callApi(path, options = {}) {
54
- const {
55
- method = 'GET',
56
- body = null,
57
- query = {},
58
- params = {}
59
- } = options;
60
-
61
- // Find the route handler
62
- const handler = apiRoutes[path];
63
-
64
- if (!handler) {
65
- return {
66
- status: 404,
67
- data: { error: 'API route not found' }
68
- };
69
- }
70
-
71
- // Create request and response objects
72
- const req = new ApiRequest(method, body, query, params);
73
- const res = new ApiResponse();
74
-
75
- try {
76
- // Call the handler
77
- await handler(req, res);
78
-
79
- return {
80
- status: res.statusCode,
81
- data: res.data,
82
- headers: res.headers
83
- };
84
- } catch (error) {
85
- console.error(`API Error on ${path}:`, error);
86
- return {
87
- status: 500,
88
- data: { error: error.message }
89
- };
90
- }
91
- }
92
-
93
- // Fetch-like API for making requests
9
+ // Fetch-like API for making requests to backend
94
10
  async function fetchApi(path, options = {}) {
95
11
  const {
96
12
  method = 'GET',
@@ -98,51 +14,31 @@ async function fetchApi(path, options = {}) {
98
14
  headers = {}
99
15
  } = options;
100
16
 
101
- // Parse query params from path
102
- const [routePath, queryString] = path.split('?');
103
- const query = {};
104
- if (queryString) {
105
- queryString.split('&').forEach(param => {
106
- const [key, value] = param.split('=');
107
- query[decodeURIComponent(key)] = decodeURIComponent(value);
108
- });
109
- }
110
-
111
- // Parse body if it's JSON
112
- let parsedBody = body;
113
- if (body && typeof body === 'string') {
114
- try {
115
- parsedBody = JSON.parse(body);
116
- } catch (e) {
117
- parsedBody = body;
17
+ const fetchOptions = {
18
+ method,
19
+ headers: {
20
+ 'Content-Type': 'application/json',
21
+ ...headers
118
22
  }
119
- }
23
+ };
120
24
 
121
- const result = await callApi(routePath.replace('/api/', ''), {
122
- method,
123
- body: parsedBody,
124
- query
125
- });
25
+ if (body) {
26
+ fetchOptions.body = typeof body === 'string' ? body : JSON.stringify(body);
27
+ }
126
28
 
127
- // Return a fetch-like response
128
- return {
129
- ok: result.status >= 200 && result.status < 300,
130
- status: result.status,
131
- statusText: result.status === 200 ? 'OK' : 'Error',
132
- headers: result.headers,
133
- json: async () => result.data,
134
- text: async () => JSON.stringify(result.data)
135
- };
29
+ try {
30
+ const response = await fetch(path, fetchOptions);
31
+ return response;
32
+ } catch (error) {
33
+ console.error('API Error:', error);
34
+ throw error;
35
+ }
136
36
  }
137
37
 
138
38
  // Export to global scope
139
- window.registerApiRoute = registerApiRoute;
140
39
  window.fetchApi = fetchApi;
141
- window.callApi = callApi;
142
40
 
143
41
  // Also make available without window prefix
144
42
  if (typeof globalThis !== 'undefined') {
145
- globalThis.registerApiRoute = registerApiRoute;
146
43
  globalThis.fetchApi = fetchApi;
147
- globalThis.callApi = callApi;
148
44
  }