niral 0.1.4 → 0.1.5

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.
Files changed (117) hide show
  1. package/LICENSE +28 -0
  2. package/README.md +494 -75
  3. package/assets/niral-logo.svg +1 -0
  4. package/bin/niral.js +437 -11
  5. package/niralscript/LICENSE +223 -0
  6. package/niralscript/README.md +269 -0
  7. package/niralscript/analysis.js +962 -0
  8. package/niralscript/check.js +10 -0
  9. package/niralscript/cli.js +147 -0
  10. package/niralscript/compile.js +354 -0
  11. package/niralscript/contracts.js +48 -0
  12. package/niralscript/errors.js +30 -0
  13. package/niralscript/expressions.js +652 -0
  14. package/niralscript/modules.js +58 -0
  15. package/niralscript/package.json +18 -0
  16. package/niralscript/parser.js +661 -0
  17. package/niralscript/scanner.js +150 -0
  18. package/niralscript/types.js +1067 -0
  19. package/package.json +19 -11
  20. package/src/add/api.js +26 -0
  21. package/src/add/auth.js +451 -0
  22. package/src/add/chat.js +96 -0
  23. package/src/add/fonts.js +75 -0
  24. package/src/add/image.js +61 -0
  25. package/src/add/imagetools.js +159 -0
  26. package/src/add/llm.js +127 -0
  27. package/src/add/sqlite.js +107 -0
  28. package/src/add/tailwind.js +123 -0
  29. package/src/add/typescript.js +73 -0
  30. package/src/build/build.js +345 -0
  31. package/src/build/bundle-runtime.js +139 -0
  32. package/src/build/export.js +71 -0
  33. package/src/check/check.js +425 -0
  34. package/src/compiler/ast.js +70 -0
  35. package/src/compiler/codegen.js +845 -0
  36. package/src/compiler/errors.js +72 -0
  37. package/src/compiler/jsx.js +460 -0
  38. package/src/compiler/niralscript.js +263 -0
  39. package/src/compiler/parser.js +490 -0
  40. package/src/compiler/rewrite.js +420 -0
  41. package/src/compiler/scanner.js +198 -0
  42. package/src/compiler/style.js +193 -0
  43. package/src/compiler/typescript.js +258 -0
  44. package/src/create.js +329 -0
  45. package/src/deploy.js +346 -0
  46. package/src/dev/client.js +205 -0
  47. package/src/dev/devtools-client.js +305 -0
  48. package/src/dev/devtools-errors.js +96 -0
  49. package/src/dev/devtools.js +119 -0
  50. package/src/dev/server.js +812 -0
  51. package/src/dev/websocket.js +145 -0
  52. package/src/di/README.md +191 -0
  53. package/src/di/agent.js +100 -0
  54. package/src/di/cli.js +243 -0
  55. package/src/di/provider.js +211 -0
  56. package/src/di/workspace.js +110 -0
  57. package/src/doctor.js +163 -0
  58. package/src/index.js +36 -0
  59. package/src/langs/go/runner.go +176 -0
  60. package/src/langs/python/runner.py +111 -0
  61. package/src/langs/ruby/runner.rb +105 -0
  62. package/src/lsp/analysis.js +226 -0
  63. package/src/lsp/niralscript.js +187 -0
  64. package/src/lsp/server.js +227 -0
  65. package/src/runtime/dom.js +760 -0
  66. package/src/runtime/forms.js +97 -0
  67. package/src/runtime/i18n.js +31 -0
  68. package/src/runtime/index.js +12 -0
  69. package/src/runtime/live.js +82 -0
  70. package/src/runtime/navigation.js +15 -0
  71. package/src/runtime/refresh.js +41 -0
  72. package/src/runtime/router.js +260 -0
  73. package/src/runtime/rpc.js +71 -0
  74. package/src/runtime/signals.js +339 -0
  75. package/src/runtime/ssr.js +164 -0
  76. package/src/server/ai.js +107 -0
  77. package/src/server/auth.js +152 -0
  78. package/src/server/backplane.js +91 -0
  79. package/src/server/context.js +48 -0
  80. package/src/server/dom-shim.js +149 -0
  81. package/src/server/endpoint-modules.js +77 -0
  82. package/src/server/endpoints.js +109 -0
  83. package/src/server/forms.js +67 -0
  84. package/src/server/hooks.js +112 -0
  85. package/src/server/i18n.js +75 -0
  86. package/src/server/integrity.js +73 -0
  87. package/src/server/jobs.js +342 -0
  88. package/src/server/live.js +194 -0
  89. package/src/server/mail.js +179 -0
  90. package/src/server/migrate.js +88 -0
  91. package/src/server/oauth.js +144 -0
  92. package/src/server/observe.js +87 -0
  93. package/src/server/page.js +135 -0
  94. package/src/server/polyglot.js +107 -0
  95. package/src/server/postgres.js +359 -0
  96. package/src/server/prod.js +779 -0
  97. package/src/server/rag.js +131 -0
  98. package/src/server/ratelimit.js +25 -0
  99. package/src/server/recover.js +183 -0
  100. package/src/server/remote-snapshot.js +231 -0
  101. package/src/server/render.js +177 -0
  102. package/src/server/router.js +132 -0
  103. package/src/server/rpc.js +264 -0
  104. package/src/server/security.js +78 -0
  105. package/src/server/session.js +135 -0
  106. package/src/server/shield.js +278 -0
  107. package/src/server/stream.js +121 -0
  108. package/src/server/uploads.js +96 -0
  109. package/src/server/watchdog.js +144 -0
  110. package/src/server/webauthn.js +245 -0
  111. package/src/server/workers.js +143 -0
  112. package/src/shared/validate.js +131 -0
  113. package/src/templates.js +254 -0
  114. package/src/test-runner.js +88 -0
  115. package/src/testing.js +41 -0
  116. package/bin/create-niral.js +0 -35
  117. package/index.js +0 -257
package/LICENSE ADDED
@@ -0,0 +1,28 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ZyoraLabs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
23
+ ---
24
+
25
+ EXCEPTION: The `niralscript/` directory contains the NiralScript compiler,
26
+ which is licensed separately under the Apache License, Version 2.0, with a
27
+ Runtime Library Exception. See `niralscript/LICENSE` for its terms. The MIT
28
+ license above does not apply to any file in that directory.
package/README.md CHANGED
@@ -1,109 +1,528 @@
1
- # Niral CLI
1
+ <div align="center">
2
2
 
3
- Zero-dependency launcher for the Niral full-stack framework. Requires Node.js 22+.
3
+ # Niral
4
4
 
5
- ## Use
5
+ **The full-stack framework with zero dependencies.**
6
+
7
+ Compiler-first components · fine-grained reactivity · SSR at Svelte speed —
8
+ served 7.5× faster than Next.js. Auth, jobs, realtime, AI and deploys built in.
9
+ `node_modules` not required.
10
+
11
+ [Docs](https://niral.site) · [Benchmarks](https://niral.site/docs/benchmarks) · [CLI reference](https://niral.site/docs/cli) · [VS Code extension](https://marketplace.visualstudio.com/items?itemName=zyoralabs.niral-vscode)
12
+
13
+ </div>
14
+
15
+ ---
16
+
17
+ ## Quick start
6
18
 
7
19
  ```sh
8
- npx niral create myapp
9
- cd myapp
10
- npx niral dev
20
+ npx create-niral my-app
21
+ cd my-app
22
+ npx niral dev # → http://localhost:5199
11
23
  ```
12
24
 
13
- Or install one global launcher:
25
+ No npm? `curl -fsSL https://niral.site/install.sh | bash` — or go direct:
14
26
 
15
27
  ```sh
16
- npm install -g niral
17
- niral create myapp --template blog
18
- niral dev myapp
28
+ git clone https://github.com/Zyora-Dev/niral.git
29
+ node niral/bin/niral.js create my-app
19
30
  ```
20
31
 
21
- Both `niral` and `create-niral` packages provide the same two executable names.
22
- Install only one globally to avoid bin conflicts. Templates: `minimal` (default),
23
- `blog`, `dashboard`. Create refuses to overwrite a nonempty project directory.
32
+ There is nothing to install. The framework is Node 22+ stdlib, end to end:
33
+ parser, compiler, reactivity, SSR, WebSockets, sessions, crypto, SQLite.
34
+ No account, no cloud, no telemetry — everything runs on your machine.
24
35
 
25
- The first project command downloads the framework from the official
26
- [repository](https://github.com/Zyora-Dev/niral) into `~/.niral/framework`.
27
- Set `NIRAL_HOME` to choose another install directory. Normal commands reuse the
28
- cached framework without checking the network. Keep projects outside that directory.
36
+ ## CLI Installation And Updates
29
37
 
30
- ## Commands
38
+ Use `npx niral <command>` in the current terminal, or open a new terminal after
39
+ scaffolding to use the generated `niral` command. For a global npm install, choose
40
+ either `npm install -g niral` or `npm install -g create-niral`; both provide the
41
+ same executable names. The framework is cached in `~/.niral/framework`, or under
42
+ `NIRAL_HOME` when configured. Keep apps outside the framework installation.
31
43
 
32
44
  ```sh
45
+ npx create-niral myblog --template blog
33
46
  npx niral --help
34
47
  npx niral --version
35
- npx niral check myapp
36
- npx niral test myapp
37
- npx niral build myapp
38
- npx niral start myapp
39
- npx niral add api myapp
40
48
  ```
41
49
 
42
- All framework commands and arguments are forwarded, with the framework's exit
43
- status preserved. See the [complete CLI reference](https://niral.site/docs/cli).
44
- `--version` reports this launcher and, when installed, the framework version.
45
- The generated direct `niral` shim reports the framework version only.
46
-
47
- ## Update
48
-
49
- Launcher 0.1.4 supports explicit framework updates and persisted revision pins:
50
+ Launcher 0.1.4 provides **explicit framework updates and revision pins**:
50
51
 
51
52
  ```sh
52
53
  npx niral@latest update
54
+ niral update
53
55
  ```
54
56
 
55
- This explicitly updates `NIRAL_HOME/framework`, even when the cached framework
56
- has no `update` command. The default is the repository's `main` branch. Updating
57
- also refreshes an existing generated shell shim so its updater remains independent
58
- of older pinned framework code. Updating the npm launcher alone does not refresh
59
- the framework; update a globally installed launcher separately with
60
- `npm install -g niral@latest`.
57
+ The first form can upgrade an older cached framework without an update command.
58
+ Normal commands reuse the cache; fetching the latest npm launcher alone does not refresh it.
59
+ Updates follow the official repository's `main` branch by default. Set `NIRAL_REF`
60
+ to a reviewed full lowercase 40-character commit SHA or existing `v`-prefixed tag
61
+ for an explicit installation/update. The selection persists across plain updates;
62
+ use `NIRAL_REF=main npx niral@latest update` to remove it. Tags can move, so use
63
+ full SHAs for reproducibility. Framework pins are independent of npm versions.
64
+ They do not modify app projects, deploy servers or update global npm packages.
65
+
66
+ Stop development/build commands before updating. Dirty/unmanaged-branch/custom-origin Git
67
+ checkouts are refused; failed Git updates never trigger destructive replacement.
68
+ Pin changes and archive replacements are staged, and the previous framework is retained as a backup,
69
+ including any local additions (not merged into the new copy). Source checkouts
70
+ outside the managed installation should be updated with Git.
71
+
72
+ See the [launcher release checklist](installer/README.md) and
73
+ [package usage](installer/niral/README.md).
74
+
75
+ ## Release Validation
76
+
77
+ `npm run test:release` runs the framework/compiler, installer recovery, immutable
78
+ build, Devtools, docs, Chromium hydration and form/navigation suites, then verifies
79
+ both npm packages contain exactly their five allowed files. It requires isolated
80
+ TypeScript and Playwright/Chromium tooling; setup is in the
81
+ [release checklist](installer/README.md). CI runs Node 22 and 24 with disposable
82
+ Postgres and image-transcoding gates. The command never publishes or deploys.
83
+
84
+ Builds finish in staging before activation. Release identity includes framework
85
+ source and generated output; identical releases are verified and reused without
86
+ rewriting published files. Failed staging leaves the active release untouched.
87
+
88
+ ## Local Devtools
89
+
90
+ Run `niral dev` and open the app directly on `localhost`, `127.0.0.1`, or `::1`.
91
+ The bottom-right Niral launcher opens a development-only inspector showing route
92
+ patterns, layout/module paths, loader timings, RPC dispatch/total durations, HTTP
93
+ statuses and failure categories. Filter requests, select details, pause updates,
94
+ refresh manually or clear the visible list. Escape closes the focused panel.
95
+
96
+ The **Errors** tab captures browser errors, unhandled promise rejections,
97
+ contained Niral runtime failures and failed RPCs (including caught calls,
98
+ network failures and streamed errors). Groups show a safe error class, source,
99
+ count and timestamps. Each tab retains up to 100 groups with the latest 20
100
+ occurrences per group; grouping uses category, class, source and action type,
101
+ not message text. Browser error history is never uploaded to the server.
102
+
103
+ RPC failures link to their exact server trace using an opaque response ID,
104
+ including overlapping requests. Calls started during a click, submit, change
105
+ or keydown handler retain that event's type and local sequence number, never
106
+ its target, text, key or input values. Calls after an async boundary are marked
107
+ unattributed rather than assigned to the most recent interaction. Transport
108
+ failures without a response have no server link; expired traces are unavailable.
109
+
110
+ Verified `.niral` client script lines link to VS Code. Mapping is conservative:
111
+ only unique, unchanged script lines are mapped; transformed or duplicate lines,
112
+ templates, JSX/TSX and unknown frames may show an unresolved line or source.
113
+ This is not a complete source map or a server exception stack. At most 512
114
+ loaded component maps are retained. Editor links include the local project file
115
+ path; server block source is never sent to the browser.
116
+
117
+ The server keeps the latest 100 completed traces in memory (up to 32 loader spans
118
+ per trace), shared across local tabs. Clear hides request history in the current
119
+ panel or empties that tab's browser error buffer, depending on the selected view.
120
+ An explicit error-to-request link can reveal a previously cleared request.
121
+ Pause stops display updates, not collection. Automatic polling runs only while
122
+ the panel is open, visible and unpaused. Numeric request IDs are local to the
123
+ server process; opaque correlation IDs also distinguish server restarts.
124
+
125
+ Only metadata is recorded: no raw request URLs, dynamic parameter values, queries,
126
+ headers, cookies, arguments, results, error messages or stacks. The read-only
127
+ endpoint requires a loopback connection, matching local Host/port, same-origin
128
+ request metadata and an inspector header; forwarded requests are rejected.
129
+ Access through LAN addresses or reverse proxies is unsupported. Do not expose a
130
+ development server publicly. Production builds do not load the inspector or
131
+ provide its endpoints. Icons use the same pinned Lucide CDN as the dev overlays.
132
+
133
+ Reactive-state inspection and dedicated form-action spans are not included.
134
+ Run `node --test tests/devtools.js` for collector, mapping and HTTP security tests;
135
+ see [browser tests](tests/browser/README.md) for UI coverage.
136
+
137
+ ## NiralScript Experiment
138
+
139
+ NiralScript is an opt-in, local compiler prototype, not a stable language release.
140
+ Its independent language extension is `.nrs`; `.niral` remains Niral's component
141
+ format. Niral is the first target; official `@niral/react`, `@niral/vite` and
142
+ `@niral/next` adapters now carry the same compiled `.nrs` modules into other
143
+ ecosystems. The
144
+ [v0.1 design draft](NIRALSCRIPT.md) distinguishes implemented and proposed features.
145
+ Use it inside an existing `.niral` component:
146
+
147
+ ```html
148
+ <script lang="niralscript">
149
+ state count = 0
150
+ derive doubled = count * 2
151
+ function increment() {
152
+ count += 1
153
+ }
154
+ </script>
155
+
156
+ <button on:click={increment}>Increase</button>
157
+ <p>{count} doubled is {doubled}</p>
158
+ ```
159
+
160
+ `state` lowers to the existing `$state` declaration and `derive` to `$derived`.
161
+ Separate declarations with a newline or semicolon; group multiline expressions
162
+ with parentheses, brackets or braces. Existing HTML, CSS, events and bindings
163
+ stay unchanged. Both declarations use Niral's existing DOM and SSR codegen.
164
+ JavaScript, TypeScript and JSX/TSX support is unchanged.
165
+
166
+ The compiler separates a source-spanned statement AST and lexical analysis from Niral emission.
167
+ Initializers are parsed into expression trees with explicit operator precedence,
168
+ collections, calls, members, conditionals and template interpolation. Validated
169
+ source is retained for compatible emission; unsupported syntax is rejected.
170
+
171
+ The independent core lives in the root-level `niralscript/` directory:
172
+ [parser](niralscript/parser.js), [expressions](niralscript/expressions.js),
173
+ [scope analysis](niralscript/analysis.js), [module linker](niralscript/modules.js), [scanner](niralscript/scanner.js) and
174
+ [diagnostics](niralscript/errors.js). It is a private, zero-dependency ES module
175
+ package with no imports from the framework. The
176
+ [Niral adapter](src/compiler/niralscript.js) emits runtime signal calls directly
177
+ from analyzed bindings and translates
178
+ language diagnostics into existing Niral errors. Tests remain in the repository's
179
+ existing test harness. Niral also loads external `.nrs` instance scripts:
180
+
181
+ ```html
182
+ <script lang="niralscript" src="./counter.nrs"></script>
183
+ ```
184
+
185
+ Paths must be explicit relative `.nrs` files inside the project, without private
186
+ paths or symlinks. Do not mix inline code with `src`. Dev reloads external edits;
187
+ SSR caches and production hashes include their contents. Raw sources stay private.
188
+
189
+ Named imports and aliases (`import { twice as scale } from "./math.nrs"`) can use
190
+ library `export const` and `export function` declarations, and modules can
191
+ re-export members of another module (`export { twice as scale } from "./math.nrs"`).
192
+ Modules keep separate scopes and initialize once per component execution, not as
193
+ process singletons. Transitive dependencies and re-export chains participate in
194
+ semantic checks, SSR invalidation, dev reloads and build hashes. Libraries cannot
195
+ declare top-level input/state/derive/let; default/namespace imports and cycles are
196
+ not supported. Private paths, including `.server.nrs`, are rejected throughout the graph.
197
+
198
+ Read-only external inputs use `input name` in inline or external instance scripts:
199
+
200
+ ```html
201
+ <server>
202
+ export function load() { return { title: "Server title" }; }
203
+ </server>
204
+ <script lang="niralscript">
205
+ input title
206
+ state draft = title
207
+ derive label = title + "!"
208
+ </script>
209
+ <h1>{label}</h1>
210
+ <input bind:value={draft} />
211
+ ```
212
+
213
+ The Niral adapter supplies same-named props, including route parameters and
214
+ explicit `load()` results. Parent updates flow to inputs and derived values
215
+ without remounting; local state initializers run once per instance. Missing
216
+ inputs are `undefined`, not a default value; explicit `null` is preserved.
217
+ Declare inputs before eager reads. Inputs and tracked aliases cannot be mutated;
218
+ bind editable controls to local state. Defaults, destructuring and input types
219
+ are not supported. Only return browser-safe values from loaders. These are
220
+ adapter rules; the independent language core has no Niral server or props imports.
221
+
222
+ The script supports top-level `input`/`state`/`derive`, ordinary `let`/`const`, named
223
+ functions, named/anonymous `function` expressions and concise/block arrows (including
224
+ `async`), lexical blocks, braced
225
+ `if`/`else`, `for...of`, `for...in`, conventional `for`/`while`, `break`/`continue`,
226
+ `try`/`catch`/`finally`, `throw`, calls, assignments and
227
+ `return`. `await` is supported inside async bodies, not at top level. Native promise
228
+ completion is preserved; async calls and explicit throws are rejected during
229
+ derived evaluation. Initialization remains conservative across await; known
230
+ awaited aliases and explicitly thrown values retain readonly checks in catches.
231
+ Catch sources are conservatively merged across explicit throws in the linked program;
232
+ unknown host returns/rejections are not a general readonly guarantee.
233
+ Nested object/array patterns work in
234
+ ordinary declarations, parameters and loops; arrays/objects support shallow spread.
235
+ Niral checks array callbacks (`map`, `filter`, `find`, `findIndex`, `some`, `every`,
236
+ `forEach`, `reduce`) and helper callback parameters resolving to one known function.
237
+ Patterns support nested defaults, array holes and final identifier rest bindings;
238
+ functions support default/rest parameters and call spread. Prefix/postfix updates
239
+ are statement-only. Destructuring assignment to existing bindings is supported with
240
+ array, object, renamed, nested, member and rest targets; object patterns must be
241
+ parenthesised and reactive `state` cannot be a destructuring target. Labels and
242
+ async iteration remain unsupported.
243
+ Scope checks reject duplicates, unresolved names, direct use before initialization
244
+ and immutable-binding writes. Resolved bindings drive signal reads/writes and
245
+ nested renames without intermediate rune discovery or script token rewriting.
246
+ The rune-emitting lowering API remains available for compatibility; template
247
+ expressions still use the existing compiler. Static checks reject detected derived effects,
248
+ cycles, readonly-alias writes and eager captured reads. Approved intrinsics are
249
+ target-specific; this is not a general purity proof for arbitrary host values.
250
+ External errors retain file/range links in component diagnostics. Gradual type
251
+ annotations, optional chaining, nullish coalescing, `typeof` and independent ESM
252
+ compilation with source maps are implemented locally. The proposed `view` syntax
253
+ is not implemented. Dedicated `.nrs` source-extension support includes compiler
254
+ diagnostics, signature/type-alias hover, completion and definition navigation. Template
255
+ handlers remain ordinary Niral/JavaScript. The subset is not a full
256
+ JavaScript grammar (regex literals and assignment expressions are rejected). It does
257
+ not establish support for arbitrary frontend languages or frameworks.
258
+
259
+ Explicit `contract<Type>(value)` expressions generate runtime data checks from
260
+ the same aliases used by the type checker. They return typed, copied data without
261
+ coercion or throw NRS081 with a field path. Ordinary annotations remain erased.
262
+ Standalone and Niral emitters support the same finite-data subset; Niral RPC
263
+ maps server-side contract failures to HTTP 400. See
264
+ [runtime contracts and limits](NIRALSCRIPT.md#compiler-generated-runtime-contracts).
61
265
 
62
- Set `APPROVED_FRAMEWORK_SHA` to a reviewed full 40-character lowercase commit SHA:
266
+ Run `node --test tests/niralscript.js` for compiler/SSR checks and
267
+ `NIRAL_BROWSER_FILTER=NiralScript node tests/browser/run.js` for dev/production
268
+ Chromium checks using the existing browser tooling. The reusable
269
+ [fixture](tests/fixtures/niralscript.niral) exercises named handlers, shadowing,
270
+ state, derived values, server-loaded inputs, local input binding, keyed lists and
271
+ RPC. Browser checks also cover parent/child updates and route parameters. These checks are
272
+ included in the release gate.
273
+
274
+ Standalone checking and compilation work from this checkout, without Niral components:
63
275
 
64
276
  ```sh
65
- NIRAL_REF="$APPROVED_FRAMEWORK_SHA" npx niral@latest update
66
- niral update
67
- NIRAL_REF=main npx niral@latest update
277
+ node niralscript/cli.js --help
278
+ node niralscript/cli.js check counter.nrs --root /path/to/project --json
279
+ node niralscript/cli.js compile counter.nrs --root /path/to/project --out counter.mjs
68
280
  ```
69
281
 
70
- The selection is saved in `NIRAL_HOME/.framework-ref`; plain updates retain it.
71
- Existing `v`-prefixed version tags are also accepted, but tags can move: use a
72
- full commit SHA for reproducibility. `NIRAL_REF=main` explicitly removes the pin.
73
- Fresh installations accept the same variable; switching a cached install requires
74
- an explicit update. npm versions and framework revisions are independent.
75
-
76
- Git installs must be clean, on `main` or a managed detached pin, and use the
77
- official HTTPS origin. `main` updates
78
- are fast-forward only; a Git failure never replaces the checkout with an archive.
79
- Pin changes and non-Git replacements are staged and syntax-checked first; the complete previous
80
- directory is retained at the printed `framework-backup-*/framework` path. Local
81
- files in that backup are not merged into the new framework. No backups are pruned.
82
-
83
- Stop active development/build commands before updating. Concurrent installers are
84
- refused. If interrupted, inspect other installer processes before manually removing
85
- a stale `NIRAL_HOME/.framework-install-lock` directory. Symlinked installs and
86
- updates invoked from unmanaged source checkouts are refused; maintain those with
87
- Git. An update does not migrate apps, publish packages or deploy/restart servers.
282
+ The `check` command validates entry files and relative module graphs without
283
+ executing source or emitting JavaScript. `compile` emits a self-contained ESM
284
+ `createInstance(inputs, globals, runtime)` factory and a `.mjs.map` file. Output
285
+ parents must exist inside the selected root; existing files are never overwritten.
286
+ The default runtime provides isolated state and pull-based cached derived reads;
287
+ hosts can inject signal/derived primitives. It does not mount a UI or subscribe.
288
+ Both commands report original file/line
289
+ diagnostics and exits 0 on success, 1 on source/file errors, or 2 on invalid usage.
290
+ It has no implicit host globals; repeat `--global name` to declare them without
291
+ asserting purity. Primitive/literal, union, array, structural record, `Promise<T>`
292
+ and function signatures check known initializers, assignments, arguments and returns.
293
+ Reusable aliases/type-only imports, generic named functions/aliases, contextual
294
+ callbacks and branch narrowing are supported. Unknown host values remain permissive
295
+ by default; opt into stricter unknown/null checks with `--strict`, the API's
296
+ `strictTypes: true`, or VS Code's `niral.niralscriptStrictTypes` (reload required).
297
+ Generic constraints, recursive aliases and generic arrows are supported; recursive
298
+ types cannot become runtime contracts.
299
+ Named classes support constructors, typed/generic fields and methods, inheritance,
300
+ private members, accessors, static blocks and `instanceof`. They emit native classes
301
+ in standalone and component output, with readonly/effect/initialization safeguards.
302
+ Class fields are ordinary properties, not automatic signals. Decorators work on
303
+ class declarations, methods, accessors and static fields. Class expressions,
304
+ dynamic computed names and TypeScript class modifiers are not supported;
305
+ see [class contracts and limitations](NIRALSCRIPT.md#classes-and-constructors).
306
+ This is not runtime validation, a fully
307
+ sound type system or Niral client/server security validation. The private package
308
+ exports `niralscript/check` and `niralscript/compile`; neither requires Niral.
309
+ See [standalone checking](NIRALSCRIPT.md#standalone-checking) and
310
+ [compilation](NIRALSCRIPT.md#standalone-compilation) for API/runtime contracts.
311
+
312
+ Run `node bench/niralscript.js` for warm compiler/string-SSR timings and generated
313
+ raw/gzip sizes for equivalent NiralScript, JavaScript and annotated TypeScript
314
+ components, all using Niral. It asserts language and DOM/string SSR parity, warms
315
+ each variant and rotates three-way batches evenly across 12 rounds. TypeScript
316
+ compilation here means Niral's type stripping, not `tsc` or type checking.
317
+ A separate paired script-backend
318
+ measurement compares direct AST emission with lowering through the JavaScript
319
+ rewriter, including parsing and analysis in both, excluding component/template
320
+ compilation.
321
+
322
+ - `node bench/niralscript.js browser`: uses the existing Playwright installation
323
+ under tests/browser to measure warm hydration and synchronous click-to-DOM
324
+ updates in headless Chromium. Asserts SSR element reuse, output and cleanup.
325
+ Creates a loopback server on an assigned free port and closes it afterwards;
326
+ no app files or existing preview servers are changed. Module loading, HTML
327
+ parsing, paint and automation transport are outside the timed regions.
328
+ - `node bench/niralscript.js types`: uses the existing TypeScript compiler resolved
329
+ by `niral check`, separately measuring fresh strict/noEmit programs with
330
+ skipLibCheck, including standard library reads/parsing. No incremental reuse or
331
+ process startup. Also asserts nine diagnostic probes covering annotated values,
332
+ records, arguments, async returns, optional/nullish access, names and effects.
333
+ Wrong-type insertion into an annotated array is rejected by both NiralScript
334
+ and strict TypeScript; unannotated NiralScript values remain dynamic.
335
+ - `node bench/niralscript.js language`: direct JavaScript vs TypeScript vs
336
+ NiralScript with identical function bodies for numeric aggregation, record
337
+ processing, strings and async/await. No components or reactive operations.
338
+ Asserts main/edge/empty outputs and input nonmutation; strict-checks each actual
339
+ TS source. Reports warmed function execution, separate source-transform times
340
+ and complete output sizes. Imports/factory setup/strict checks excluded from
341
+ runtime timings. All execute as JavaScript on the same V8 engine; compiler
342
+ timings differ in checking work, and NRS output includes unused runtime glue.
343
+ - GitHub Actions: the `compare-languages` job in Release Checks configures separate
344
+ Ubuntu24.04 jobs on Node22/24 with TypeScript5.7.3 and three sequential `language`
345
+ runs per job. Artifacts contain logs and commit/runtime/hardware metadata for
346
+ 30 days. Correctness failures fail CI; timings are informational because hosted
347
+ runners vary. The workflow and all compiler changes must be committed/pushed
348
+ before a GitHub run can test them.
349
+ - `node bench/niralscript.js standalone`: independently compiles typed `.nrs` to
350
+ ESM and TypeScript via `transpileModule`, alongside an untransformed JS reference.
351
+ Asserts counter/collection outputs, instance isolation, input updates/reset and
352
+ async success/catch. Reports complete module/map sizes, warm transform times and
353
+ balanced runtime batches (100 writes+reads or 1000 unchanged reads), including
354
+ fresh instance creation. NRS bundles its pull/cached runtime; JS/TS implement
355
+ only the measured interface with direct variables/recomputed reads. Array copies
356
+ and mapping are identical; the standalone host explicitly approves native array
357
+ `map` on literal arrays. Only valid supplied input values are compared. TS
358
+ transpilation is not strict checking; maps and runtime strategies differ, so
359
+ transform/size numbers are not equivalent compiler-work or feature comparisons.
360
+
361
+ These are local microbenchmarks, not cross-framework or end-user latency rankings.
362
+ Recorded results, versions and limitations are in [PROGRESS.md](PROGRESS.md).
88
363
 
89
364
  ## Developer Intelligence
90
365
 
366
+ Niral DI runs through the existing CLI, with your exact provider and model:
367
+
91
368
  ```sh
92
- npx niral di setup
93
- npx niral di status
94
- npx niral di ask "Explain this project" --root ./myapp --read-only
95
- npx niral di chat --root ./myapp
96
- npx niral di new myblog "Customize the home page" --template blog
369
+ niral di setup
370
+ niral di status
371
+ niral di ask "Explain the routes" --read-only
372
+ niral di chat
373
+ niral di new myblog "Customize the home page" --template blog
374
+ ```
375
+
376
+ Setup offers OpenAI, Claude (Anthropic), Azure OpenAI or Custom. Named providers
377
+ set protocol/auth automatically; Custom keeps manual choices. You supply the exact
378
+ model and credential variable name, not the key. Bedrock is not yet supported.
379
+ Explicit flags remain available through `niral di setup --help`.
380
+ Set the named credential variable privately in your terminal. Setup stores no
381
+ key; every workspace tool needs interactive approval. Writes check the current
382
+ file hash and retain external backups. Use `--no-tools` with `ask` for prompt-only
383
+ automation. No shell execution, automatic testing or cloud account requirement.
384
+ Read the [DI command and safety guide](src/di/README.md) before granting file access.
385
+
386
+ ## One file, whole feature
387
+
388
+ ```html
389
+ <server>
390
+ export async function load() {
391
+ return { items: await db.all() } // SSR data — never ships
392
+ }
393
+ export async function add(text) {
394
+ publish("todos", { text }) // realtime to every tab
395
+ }
396
+ </server>
397
+
398
+ <script>
399
+ let { items } = $props
400
+ let list = $state(items)
401
+ live("todos", (t) => list = [...list, t])
402
+ </script>
403
+
404
+ {#for t of list key t.id}
405
+ <li transition:fade>{t.text}</li>
406
+ {/for}
97
407
  ```
98
408
 
99
- `npx niral di setup` offers OpenAI, Claude (Anthropic), Azure OpenAI or Custom.
100
- Named providers set protocol/auth automatically; Custom keeps manual choices.
101
- Enter your exact model/deployment and credential variable name. Azure also asks
102
- for its resource URL or `/openai/v1` base. Bedrock is not yet supported.
103
- Use `npx niral di setup --help` for noninteractive flags.
104
- Credentials stay in a named environment variable, not config or project files.
105
- File reads/edits require a terminal and per-tool approval; writes retain backups
106
- and reject stale hashes. `ask <prompt> --no-tools` permits prompt-only automation.
107
- No unrestricted shell, automatic tests, transcript persistence or Niral Cloud
108
- requirement. See the [DI commands and safeguards](https://niral.site/docs/cli).
109
- Existing cached frameworks need `npx niral@latest update` to acquire DI commands.
409
+ `load()` runs on the server per request. `add()` becomes a type-safe RPC —
410
+ the compiler splits server and client code, so secrets structurally cannot
411
+ reach the browser (reading `process.env` in client code is a **compile error**).
412
+
413
+ ## Measured, not marketed
414
+
415
+ End-to-end — each framework's own production server, dynamic SSR on every
416
+ request, the same 1000-row page, 100 connections × 10 s
417
+ ([methodology + run it yourself](bench/e2e/)):
418
+
419
+ | framework | req/s | p50 | p99 | build |
420
+ |-----------|------:|----:|----:|------:|
421
+ | **niral** | **~2,200** | **40 ms** | ~150 ms | **0.2 s** |
422
+ | sveltekit 2 (svelte 5) | ~580 | 128 ms | ~1.6 s | 2.3–3.7 s |
423
+ | next 16 (react 19) | ~290 | 310 ms | 2.3–3.2 s | 3.3–5.5 s |
424
+
425
+ Hydration ties Svelte (6.6 ms / 1000 rows) at 29.7 KB of JS — [bench/hydration/](bench/hydration/).
426
+
427
+ **Streaming SSR — time to first byte** with a 300 ms slow data source
428
+ ([run it yourself](bench/streaming/)). Streaming flushes the shell before the
429
+ slow value; `total` stays ~300 ms, but the page paints in single-digit ms:
430
+
431
+ | framework | blocking TTFB | streaming TTFB | streamed data |
432
+ |-----------|--------------:|---------------:|---------------|
433
+ | **niral** | 304 ms | **2 ms** | server-rendered HTML |
434
+ | next 16 | 307 ms | 6 ms | server-rendered HTML |
435
+ | sveltekit 2 | 305 ms | 3 ms | client-resolved payload |
436
+
437
+ ## What's in the box
438
+
439
+ - **Components** — `.niral` single-file components, runes (`$state`, `$props`), keyed lists, transitions, context, slots
440
+ - **SSR + hydration** — dual codegen: DOM builder for the client, string renderer for the server, byte-identical output
441
+ - **Streaming SSR** — `<script stream>` flushes the shell first, then streams each `{#await}` branch out of order as its promise settles (server-rendered HTML, revealed with zero framework JS). ~2 ms first byte vs ~300 ms blocking — [bench/streaming/](bench/streaming/)
442
+ - **Server functions** — `<server>` blocks become RPC with compile-time stubs, streaming (async generators → NDJSON), form actions that work without JS
443
+ - **Polyglot** — server blocks in Python, Ruby or Go; same sessions, same RPC
444
+ - **Auth** — passkeys, passwords, TOTP 2FA, OAuth, route guards (`niral add auth` — scaffolded code you own)
445
+ - **Realtime** — live channels on framework-owned WebSockets, session-aware guards
446
+ - **Jobs & cron** — durable SQLite queue that survives deploys; retries, backoff, dead-letters
447
+ - **AI-native** — `ai.chat` / `ai.stream` / `ai.embed` against any OpenAI-compatible endpoint, RAG included, fully-local option (`niral add llm`)
448
+ - **Data** — SQL migrations that auto-apply at boot; `node:sqlite` everywhere
449
+ - **Quality** — `niral test` (boots your real app), `niral check` (the actual TypeScript compiler), `niral doctor`
450
+ - **Ship** — content-hashed atomic releases, one-symlink rollback, graceful drains, generated systemd + nginx + Dockerfile deploy kit, CSP nonces and security headers by default
451
+ - **Recover off-box** — gzip + scrypt + AES-256-GCM snapshots to any S3-compatible store, native SigV4, remote retention and authenticated restore
452
+ - **More** — i18n, SMTP mail, image pipeline, structured logging with request IDs, LSP + VS Code extension
453
+
454
+ ## Editor & AI support
455
+
456
+ - **VS Code** — install the [Niral extension](https://marketplace.visualstudio.com/items?itemName=zyoralabs.niral-vscode) (`zyoralabs.niral-vscode`) for `.niral` syntax highlighting, diagnostics, completions and hover docs, backed by the built-in language server (`niral lsp`).
457
+
458
+ ```sh
459
+ code --install-extension zyoralabs.niral-vscode
460
+ ```
461
+ - **AI agents** — every project scaffolds an `AGENTS.md`, so Copilot / Claude / Cursor understand Niral's conventions natively instead of guessing “Svelte-ish.” New apps also drop a `.vscode/extensions.json` that recommends the extension the moment the folder opens. Agents can run `niral check` / `niral test` to verify their own edits against the real compiler.
462
+
463
+ ## Secrets can't escape
464
+
465
+ 1. `process.env` in client code → **compile error**
466
+ 2. Env files never enter a build
467
+ 3. Dev and prod servers refuse to serve them
468
+ 4. Scaffolded `.gitignore` keeps them out of git
469
+ 5. The deploy script never syncs them — production secrets live only on the server
470
+
471
+ ### Security Boundaries
472
+
473
+ Use a currently supported, security-patched Node.js release. The
474
+ [October 21, 2026 Node advisory](https://nodejs.org/en/blog/vulnerability/october-2026-security-releases)
475
+ lists fixes in 22.23.4, 24.22.1 and 26.12.1; use those or a newer patched release
476
+ in a supported line. Framework checks cannot patch Node's DNS, TLS, HTTP or
477
+ decompression internals. PHP is not a Niral runtime.
478
+
479
+ - Private directory/file exclusions are case-insensitive, including nested
480
+ `data/`, dotfiles, environment files and server modules. Public symlinks and
481
+ Windows junctions are not served or traversed by the static build walker.
482
+ Use regular copies for intentionally public assets.
483
+ - Raw `.niral`, `.jsx` and `.tsx` component sources are never copied into static
484
+ build output. Dev requests with noncanonical component-extension case are
485
+ rejected instead of returning uncompiled source.
486
+ - Decoded paths containing backslashes, colons, control characters, dot segments,
487
+ or segments ending in a dot or space return 400, including dynamic route paths.
488
+ - RPC still requires `x-niral-rpc: 1` and now shares form-origin validation.
489
+ Configure `NIRAL_ORIGIN` to the exact public origin (scheme, hostname and port)
490
+ for strict origin matching behind a TLS-terminating proxy. Without that setting,
491
+ unencrypted connections retain host-and-port matching for proxy compatibility.
492
+ Requests without Origin remain allowed unless Fetch Metadata says cross-site;
493
+ this is not authentication or authorization for an application's functions.
494
+
495
+ Rebuild applications after upgrading: previously generated static files may
496
+ already contain copied private data or raw components. Keep development servers
497
+ private, enforce application authorization, and protect release directories from
498
+ untrusted writes. These checks do not sandbox server code or protect against
499
+ malicious local filesystem races/hard links, runtime CVEs or volumetric DDoS.
500
+
501
+ ## Repository layout
502
+
503
+ ```
504
+ bin/niral.js the CLI — create · dev · check · test · migrate · build · start · deploy · doctor · snapshot/restore
505
+ src/compiler/ parser, codegen (DOM + string-SSR), rewriter
506
+ src/runtime/ signals, DOM ops, hydration, router, i18n, rpc client
507
+ src/server/ dev + prod servers, sessions, auth, jobs, live, ai, rag, migrate
508
+ src/add/ recipes: tailwind · sqlite · fonts · image · auth · typescript · chat · llm
509
+ apps/docs/ the documentation site — a niral app (dogfood)
510
+ apps/quickpoll/ realtime polling app (dogfood)
511
+ bench/ reproducible benchmarks — e2e throughput + streaming TTFB, vs Next.js, SvelteKit, SolidStart, Astro
512
+ tests/ 161 tests — npm test
513
+ editors/vscode/ syntax highlighting + LSP client
514
+ ```
515
+
516
+ ## Philosophy
517
+
518
+ - **Compiler, not runtime.** The work happens once, at build time.
519
+ - **Zero dependencies, forever.** No supply chain, no audits, no upstream breakage. Every line that runs is a line you can read.
520
+ - **Honest measurement.** Every benchmark in this repo is reproducible. We'd rather you check.
521
+
522
+ ---
523
+
524
+ <div align="center">
525
+
526
+ நிரல் — "program" in Tamil · Built in India · Powered by [ZyoraLabs](https://zyoralabs.com)
527
+
528
+ </div>