nitro5 1.0.0
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/.install.js +158 -0
- package/README.md +258 -0
- package/binding.gyp +25 -0
- package/index.js +54 -0
- package/native/nitro5.cc +742 -0
- package/nitro5.config.js +8 -0
- package/package.json +62 -0
- package/public/app.tsx +10 -0
- package/public/index.html +10 -0
- package/public/main.tsx +5 -0
- package/src/app.js +1162 -0
- package/src/cache.js +53 -0
- package/src/dashboard.js +215 -0
- package/src/deps-cache.js +37 -0
- package/src/disk-cache.js +37 -0
- package/src/file-worker.js +19 -0
- package/src/hmr.js +38 -0
- package/src/logger.js +51 -0
- package/src/mime.js +32 -0
- package/src/msg.js +16 -0
- package/src/native.js +75 -0
- package/src/router.js +85 -0
- package/src/stat.js +25 -0
- package/src/static.js +201 -0
- package/src/stats.js +25 -0
- package/src/supervisor.js +249 -0
- package/src/thread-pool.js +107 -0
- package/src/tsc.js +329 -0
- package/src/vite.js +15 -0
- package/src/watcher.js +63 -0
package/.install.js
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { exec as execCb, execSync } from "node:child_process";
|
|
2
|
+
import readline from "node:readline";
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
|
|
6
|
+
function ask(question) {
|
|
7
|
+
const rl = readline.createInterface({
|
|
8
|
+
input: process.stdin,
|
|
9
|
+
output: process.stdout
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
return new Promise((resolve) => {
|
|
13
|
+
rl.question(question, (answer) => {
|
|
14
|
+
rl.close();
|
|
15
|
+
resolve(answer);
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function run(cmd) {
|
|
21
|
+
return new Promise((resolve, reject) => {
|
|
22
|
+
execCb(
|
|
23
|
+
cmd,
|
|
24
|
+
{
|
|
25
|
+
shell: true,
|
|
26
|
+
env: {
|
|
27
|
+
...process.env,
|
|
28
|
+
GYP_DEFINES: process.env.GYP_DEFINES || "android_ndk_path="
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
(err, stdout, stderr) => {
|
|
32
|
+
if (stdout) process.stdout.write(stdout);
|
|
33
|
+
if (stderr) process.stderr.write(stderr);
|
|
34
|
+
|
|
35
|
+
if (err) reject(err);
|
|
36
|
+
else resolve();
|
|
37
|
+
}
|
|
38
|
+
);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function runSync(cmd) {
|
|
43
|
+
execSync(cmd, {
|
|
44
|
+
stdio: "inherit",
|
|
45
|
+
shell: true,
|
|
46
|
+
env: {
|
|
47
|
+
...process.env,
|
|
48
|
+
GYP_DEFINES: process.env.GYP_DEFINES || "android_ndk_path="
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function write(file, content = "") {
|
|
54
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
55
|
+
fs.writeFileSync(file, content, "utf8");
|
|
56
|
+
console.log("✔", file);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function main() {
|
|
60
|
+
console.log("🚀 Nitro5 installer starting...\n");
|
|
61
|
+
|
|
62
|
+
process.env.GYP_DEFINES = "android_ndk_path=";
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
console.log("📦 Installing dependencies...");
|
|
66
|
+
runSync("npm install --ignore-scripts --silent");
|
|
67
|
+
console.log("[Nitro 5]: Dependencies installed");
|
|
68
|
+
} catch (err) {
|
|
69
|
+
console.error("❌ Failed to install dependencies");
|
|
70
|
+
throw err;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
console.log("\n🔧 Building native addon...");
|
|
75
|
+
await run("npm install -g node-gyp --silent");
|
|
76
|
+
await run("node-gyp rebuild");
|
|
77
|
+
console.log("[Nitro 5]: Native build complete");
|
|
78
|
+
} catch (err) {
|
|
79
|
+
console.warn("⚠️ Native build failed, continuing without stopping installer.");
|
|
80
|
+
console.warn(String(err?.message || err));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
write(
|
|
84
|
+
"nitro5.config.js",
|
|
85
|
+
`export default {
|
|
86
|
+
server: { port: 3000 },
|
|
87
|
+
dev: { useVite: false },
|
|
88
|
+
cache: { enabled: true, ttl: 60 },
|
|
89
|
+
cors: { enabled: true, origin: "*" },
|
|
90
|
+
cacheTs: true,
|
|
91
|
+
dashboard: true
|
|
92
|
+
};
|
|
93
|
+
`
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
write(
|
|
97
|
+
"public/index.html",
|
|
98
|
+
`<!DOCTYPE html>
|
|
99
|
+
<html>
|
|
100
|
+
<head>
|
|
101
|
+
<meta charset="UTF-8" />
|
|
102
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
103
|
+
<title>Nitro5 + React 19</title>
|
|
104
|
+
</head>
|
|
105
|
+
<body>
|
|
106
|
+
<div id="app"></div>
|
|
107
|
+
<script type="module" src="./main.tsx"></script>
|
|
108
|
+
</body>
|
|
109
|
+
</html>
|
|
110
|
+
`
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
write(
|
|
114
|
+
"public/app.tsx",
|
|
115
|
+
`import React from "react";
|
|
116
|
+
|
|
117
|
+
export function App() {
|
|
118
|
+
return (
|
|
119
|
+
<div>
|
|
120
|
+
<h1>Nitro5 + React 19 🚀</h1>
|
|
121
|
+
<p>Web server ready!</p>
|
|
122
|
+
</div>
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
`
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
write(
|
|
129
|
+
"public/main.tsx",
|
|
130
|
+
`import React from "react";
|
|
131
|
+
import { createRoot } from "react-dom/client";
|
|
132
|
+
import { App } from "./app";
|
|
133
|
+
|
|
134
|
+
createRoot(document.getElementById("app")!).render(<App />);
|
|
135
|
+
`
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
const answer = await ask("\nUninstall node-gyp globally? (y/N): ");
|
|
139
|
+
|
|
140
|
+
if (answer.trim().toLowerCase() === "y") {
|
|
141
|
+
try {
|
|
142
|
+
await run("npm uninstall -g node-gyp");
|
|
143
|
+
console.log("🗑️ node-gyp removed");
|
|
144
|
+
} catch (err) {
|
|
145
|
+
console.warn("⚠️ Failed to uninstall node-gyp globally.");
|
|
146
|
+
}
|
|
147
|
+
} else {
|
|
148
|
+
console.log("👍 kept node-gyp");
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
console.log("\n🔥 Nitro5 setup complete!");
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
main().catch((err) => {
|
|
155
|
+
console.error("\n❌ Nitro5 installer failed:");
|
|
156
|
+
console.error(err);
|
|
157
|
+
process.exitCode = 1;
|
|
158
|
+
});
|
package/README.md
ADDED
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
# Nitro 5 — Web Server
|
|
2
|
+
|
|
3
|
+
<img align="center" src="https://img.shields.io/badge/Open%20Source-GitHub-black?style=for-the-badge&logo=github" />
|
|
4
|
+
<img align="center" src="https://img.shields.io/badge/License-BSD%203--Clause-blue?style=for-the-badge&logo=open-source-initiative" />
|
|
5
|
+
|
|
6
|
+
[](https://nitro5.opendnf.cloud/)
|
|
7
|
+

|
|
8
|
+

|
|
9
|
+
|
|
10
|
+

|
|
11
|
+

|
|
12
|
+

|
|
13
|
+
|
|
14
|
+

|
|
15
|
+

|
|
16
|
+

|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Overview
|
|
21
|
+
|
|
22
|
+
Nitro 5 is a high-performance web server framework built with a hybrid architecture of **Node.js** and **C++**. It is designed to provide fast, predictable, and efficient request handling while maintaining a modern and developer-friendly ecosystem.
|
|
23
|
+
|
|
24
|
+
At its core, Nitro 5 uses Node.js to manage application-level logic, routing, and server-side JavaScript execution. C++ is reserved for performance-critical components such as low-level networking, request processing, and system-level optimization. This architecture is intended to deliver improved speed, lower latency, and better resource efficiency compared to traditional JavaScript-only server implementations.
|
|
25
|
+
|
|
26
|
+
Nitro 5 also provides built-in support for **TypeScript** and **JSX/TSX**, making it suitable for modern frontend and backend workflows. With an **ESBuild-powered** bundler, Nitro 5 can compile and transform modern JavaScript and TypeScript code with exceptional speed. This helps developers maintain a rapid development loop while preserving production performance.
|
|
27
|
+
|
|
28
|
+
In addition, Nitro 5 is designed with predictability and scalability in mind. Its architecture emphasizes consistent behavior under load, making it well suited for real-time applications, REST APIs, microservices, and larger web systems. By separating high-level application logic from low-level optimization, Nitro 5 aims to remain both flexible and highly optimized.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Nitro 5 Delivers
|
|
33
|
+
|
|
34
|
+
Nitro 5 includes the following capabilities:
|
|
35
|
+
|
|
36
|
+
- Scalable web server architecture
|
|
37
|
+
- TypeScript support
|
|
38
|
+
- TypeScript cache
|
|
39
|
+
- JSX / TSX support for React
|
|
40
|
+
- Vite support
|
|
41
|
+
- Hot Module Replacement (HMR)
|
|
42
|
+
- Caching
|
|
43
|
+
- Watcher mode
|
|
44
|
+
- Router
|
|
45
|
+
- Dashboard
|
|
46
|
+
- Thread workers
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Key Highlights
|
|
51
|
+
|
|
52
|
+
Nitro 5 is intended for developers who want:
|
|
53
|
+
|
|
54
|
+
- A modern web server foundation
|
|
55
|
+
- Strong developer ergonomics
|
|
56
|
+
- Fast compilation and rebuild times
|
|
57
|
+
- Clean support for TypeScript and TSX
|
|
58
|
+
- A system that can evolve into a production-oriented framework
|
|
59
|
+
- A balance between productivity and native performance
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Architecture
|
|
64
|
+
|
|
65
|
+
Nitro 5 is organized around several layers of responsibility:
|
|
66
|
+
|
|
67
|
+
### Application Layer
|
|
68
|
+
Handles routing, middleware, application logic, configuration, and framework-level behavior.
|
|
69
|
+
|
|
70
|
+
### Runtime Layer
|
|
71
|
+
Provides the Node.js execution environment and coordinates server operations.
|
|
72
|
+
|
|
73
|
+
### Performance Layer
|
|
74
|
+
Uses C++ bindings for lower-level optimizations, request handling, and performance-sensitive execution paths.
|
|
75
|
+
|
|
76
|
+
### Build Layer
|
|
77
|
+
Uses ESBuild to handle fast transformations for TypeScript, TSX, and modern module workflows.
|
|
78
|
+
|
|
79
|
+
This layered structure is designed to support both development speed and runtime efficiency.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## How to Use
|
|
84
|
+
|
|
85
|
+
### 1. Install the C/C++ Toolchain
|
|
86
|
+
|
|
87
|
+
Before installing Nitro 5, make sure a C/C++ compiler is available in your environment.
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
apt install clang
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### 2. Install Nitro 5
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
npm install nitro5
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### 3. Wait for Postinstall
|
|
100
|
+
|
|
101
|
+
Nitro 5 will automatically build native modules using C++ bindings during the postinstall process.
|
|
102
|
+
|
|
103
|
+
### 4. Run the Nitro 5 CLI
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
nitro5
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 5. Open the Local Server
|
|
110
|
+
|
|
111
|
+
Visit:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
http://localhost:3000/
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
You should then see the Nitro 5 web server running in your browser.
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Example Configuration
|
|
122
|
+
|
|
123
|
+
A typical Nitro 5 project may include a `nitro5.config.js` file like the following:
|
|
124
|
+
|
|
125
|
+
```js
|
|
126
|
+
export default {
|
|
127
|
+
server: {
|
|
128
|
+
port: 3000,
|
|
129
|
+
},
|
|
130
|
+
dev: {
|
|
131
|
+
useVite: false
|
|
132
|
+
},
|
|
133
|
+
cache: {
|
|
134
|
+
enabled: true,
|
|
135
|
+
ttl: 60
|
|
136
|
+
},
|
|
137
|
+
dashboard: true,
|
|
138
|
+
cors: {
|
|
139
|
+
enabled: true,
|
|
140
|
+
origin: "*"
|
|
141
|
+
},
|
|
142
|
+
cacheTs: true
|
|
143
|
+
};
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Example Project Structure
|
|
149
|
+
|
|
150
|
+
A common project layout may look like this:
|
|
151
|
+
|
|
152
|
+
```txt
|
|
153
|
+
.
|
|
154
|
+
|____ nitro5.config.js
|
|
155
|
+
|
|
|
156
|
+
|__ public
|
|
157
|
+
|___ index.html
|
|
158
|
+
|___ app.tsx
|
|
159
|
+
|___ main.ts
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Example Frontend Setup
|
|
165
|
+
|
|
166
|
+
### `public/index.html`
|
|
167
|
+
|
|
168
|
+
```html
|
|
169
|
+
<!DOCTYPE html>
|
|
170
|
+
<html>
|
|
171
|
+
<head>
|
|
172
|
+
<meta charset="UTF-8" />
|
|
173
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
174
|
+
<title>Nitro 5</title>
|
|
175
|
+
</head>
|
|
176
|
+
<body>
|
|
177
|
+
<div id="app"></div>
|
|
178
|
+
<script type="module" src="./main.tsx"></script>
|
|
179
|
+
</body>
|
|
180
|
+
</html>
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### `public/app.tsx`
|
|
184
|
+
|
|
185
|
+
```tsx
|
|
186
|
+
import React from "react";
|
|
187
|
+
|
|
188
|
+
export function App() {
|
|
189
|
+
return (
|
|
190
|
+
<div>
|
|
191
|
+
<h1>Nitro5 + React 19 🚀</h1>
|
|
192
|
+
<p>Web server ready!</p>
|
|
193
|
+
</div>
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### `public/main.ts`
|
|
199
|
+
|
|
200
|
+
```ts
|
|
201
|
+
import React from "react";
|
|
202
|
+
import { createRoot } from "react-dom/client";
|
|
203
|
+
import { App } from "./app";
|
|
204
|
+
|
|
205
|
+
createRoot(document.getElementById("app")!).render(<App />);
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## Why Nitro 5
|
|
211
|
+
|
|
212
|
+
Nitro 5 is intended for developers who want:
|
|
213
|
+
|
|
214
|
+
- High runtime performance
|
|
215
|
+
- A TypeScript-first development experience
|
|
216
|
+
- React and TSX support
|
|
217
|
+
- Fast rebuilds and iteration
|
|
218
|
+
- A scalable architecture for real-world applications
|
|
219
|
+
- A framework that balances developer productivity with native performance
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## Contribution
|
|
224
|
+
|
|
225
|
+
Contributions are welcome.
|
|
226
|
+
|
|
227
|
+
If you find a bug, please open an issue or submit a pull request in the GitHub repository.
|
|
228
|
+
|
|
229
|
+
Before contributing, please ensure that your changes are clear, consistent, and aligned with the project’s architecture and style.
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## Roadmap
|
|
234
|
+
|
|
235
|
+
Planned and potential future improvements may include:
|
|
236
|
+
|
|
237
|
+
- Improved developer dashboard
|
|
238
|
+
- Enhanced caching controls
|
|
239
|
+
- Better TypeScript tooling
|
|
240
|
+
- Expanded plugin support
|
|
241
|
+
- More advanced HMR integration
|
|
242
|
+
- Multi-threaded request optimization
|
|
243
|
+
- Additional router features
|
|
244
|
+
- Production build optimizations
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## License
|
|
249
|
+
|
|
250
|
+
This project is licensed under the **BSD 3-Clause License**.
|
|
251
|
+
|
|
252
|
+
Copyright (C) 2026 OpenDN Foundation
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
## Project Website
|
|
257
|
+
|
|
258
|
+
Official website: https://nitro5.opendnf.cloud/
|
package/binding.gyp
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"targets": [
|
|
3
|
+
{
|
|
4
|
+
"target_name": "nitro5",
|
|
5
|
+
"sources": [
|
|
6
|
+
"native/nitro5.cc"
|
|
7
|
+
],
|
|
8
|
+
"include_dirs": [
|
|
9
|
+
"<!@(node -p \"require('node-addon-api').include\")"
|
|
10
|
+
],
|
|
11
|
+
"dependencies": [
|
|
12
|
+
"<!(node -p \"require('node-addon-api').gyp\")"
|
|
13
|
+
],
|
|
14
|
+
"defines": [
|
|
15
|
+
"NAPI_CPP_EXCEPTIONS"
|
|
16
|
+
],
|
|
17
|
+
"cflags_cc!": [
|
|
18
|
+
"-fno-exceptions"
|
|
19
|
+
],
|
|
20
|
+
"cflags_cc": [
|
|
21
|
+
"-std=c++17"
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
package/index.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#!/usr/bin/node
|
|
2
|
+
import cluster from "node:cluster";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import ora from "ora";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
import { startSupervisor } from "./src/supervisor.js";
|
|
8
|
+
import msg from "./src/msg.js";
|
|
9
|
+
|
|
10
|
+
// =======================
|
|
11
|
+
// Resolve config safely
|
|
12
|
+
// =======================
|
|
13
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
14
|
+
const __dirname = path.dirname(__filename);
|
|
15
|
+
|
|
16
|
+
let config;
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
const configPath = path.join(process.cwd(), "nitro5.config.js");
|
|
20
|
+
config = (await import(configPath)).default;
|
|
21
|
+
} catch (err) {
|
|
22
|
+
throw new Error(msg.noConfigFound);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (!config || typeof config !== "object") {
|
|
26
|
+
throw new Error(msg.noConfigFound);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// =======================
|
|
30
|
+
// Cluster mode
|
|
31
|
+
// =======================
|
|
32
|
+
const isPrimary = cluster.isPrimary || cluster.isMaster;
|
|
33
|
+
|
|
34
|
+
if (isPrimary) {
|
|
35
|
+
console.log(chalk.blue(msg.info));
|
|
36
|
+
|
|
37
|
+
const spinner = ora("Starting Nitro5...").start();
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
await startSupervisor(config);
|
|
41
|
+
|
|
42
|
+
const port = config?.server?.port ?? config?.port ?? 3000;
|
|
43
|
+
|
|
44
|
+
spinner.succeed(
|
|
45
|
+
chalk.green(`Nitro5 ready on port ${port}`)
|
|
46
|
+
);
|
|
47
|
+
} catch (error) {
|
|
48
|
+
spinner.fail(chalk.red("Nitro5 failed to start"));
|
|
49
|
+
console.error(error);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
} else {
|
|
53
|
+
await startSupervisor(config);
|
|
54
|
+
}
|