@punkestu/react-html 0.0.0-stage โ†’ 0.1.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.
@@ -0,0 +1,9 @@
1
+ // .server-test-fixture/src/pages/index.tsx
2
+ import { jsx } from "react/jsx-runtime";
3
+ function Home() {
4
+ return /* @__PURE__ */ jsx("h1", { children: "UPDATED LIVE IN DEV" });
5
+ }
6
+ export {
7
+ Home as default
8
+ };
9
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLnNlcnZlci10ZXN0LWZpeHR1cmUvc3JjL3BhZ2VzL2luZGV4LnRzeCJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiXG4gICAgICAgIGltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG4gICAgICAgIGV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEhvbWUoKSB7XG4gICAgICAgICAgcmV0dXJuIDxoMT5VUERBVEVEIExJVkUgSU4gREVWPC9oMT47XG4gICAgICAgIH1cbiAgICAgICAgIl0sCiAgIm1hcHBpbmdzIjogIjtBQUdpQjtBQURNLFNBQVIsT0FBd0I7QUFDN0IsU0FBTyxvQkFBQyxRQUFHLGlDQUFtQjtBQUNoQzsiLAogICJuYW1lcyI6IFtdCn0K
package/DOCS.md ADDED
@@ -0,0 +1,317 @@
1
+ # ๐Ÿ“– react-html Complete Manual & Documentation
2
+
3
+ A high-performance static engine to compile React/JSX to **pure, semantic HTML** with selective reactive compilation for interactive components via an **Islands Architecture**.
4
+
5
+ > ๐Ÿ’ก **Terminal UI Access**: You can also browse this documentation interactively in your terminal by running:
6
+ > ```bash
7
+ > npx react-html docs
8
+ > # Or print a specific section:
9
+ > npx react-html docs islands
10
+ > ```
11
+
12
+ ---
13
+
14
+ ## Table of Contents
15
+
16
+ 1. [Overview & Philosophy](#1-overview--philosophy)
17
+ 2. [Getting Started & Setup](#2-getting-started--setup)
18
+ 3. [Modular HTML with React](#3-modular-html-with-react)
19
+ 4. [Reactive Islands Architecture](#4-reactive-islands-architecture)
20
+ 5. [Hydration Directives](#5-hydration-directives)
21
+ 6. [CLI Commands & Options](#6-cli-commands--options)
22
+ 7. [Programmatic API Reference](#7-programmatic-api-reference)
23
+ 8. [Server App Integration (Express, Fastify, Node HTTP)](#8-server-app-integration-express-fastify-node-http)
24
+ 9. [Best Practices & Troubleshooting](#9-best-practices--troubleshooting)
25
+
26
+ ---
27
+
28
+ ## 1. Overview & Philosophy
29
+
30
+ Modern web development often forces a painful choice:
31
+ - **Write raw HTML/handlebars/nunjucks**: You lose type safety, component modularity, and rich JSX composition.
32
+ - **Use modern React frameworks (Next.js, CRA, Remix)**: You inadvertently ship massive megabytes of JavaScript, client routers, and heavy hydration runtimes even for mostly static pages.
33
+
34
+ **`react-html` gives you the best of both worlds**:
35
+ 1. **Zero JavaScript by Default**:
36
+ Pages without interactive islands output 100% pure, clean HTML5. No client-side React runtime, no `data-reactroot` attributes, and 0 KB JavaScript sent to visitors.
37
+ 2. **Modular & DRY Components**:
38
+ Compose your pages with `<Layout>`, `<Header>`, `<Card>`, `<Footer>`, loops, and conditionals using standard React and TypeScript.
39
+ 3. **Selective Reactivity**:
40
+ Interactive components (counters, carousels, modals, filters) are marked as **Islands**. The engine pre-renders their initial markup for instant paint and bundles only that component into a standalone client script using `esbuild`.
41
+
42
+ ---
43
+
44
+ ## 2. Getting Started & Setup
45
+
46
+ ### Prerequisites
47
+ - Standard **Node.js v20.0.0 or higher** with `npm` (no Bun dependencies).
48
+
49
+ ### Installation
50
+ ```bash
51
+ npm install react-html
52
+ ```
53
+
54
+ Or clone and link locally:
55
+ ```bash
56
+ git clone https://github.com/microapes/react-html.git
57
+ cd react-html
58
+ npm install
59
+ npm run build
60
+ npm link
61
+ ```
62
+
63
+ ### Recommended Directory Structure
64
+
65
+ ```text
66
+ my-project/
67
+ โ”œโ”€โ”€ package.json
68
+ โ”œโ”€โ”€ public/ # Static files copied to dist/ verbatim
69
+ โ”‚ โ”œโ”€โ”€ favicon.ico
70
+ โ”‚ โ””โ”€โ”€ styles.css
71
+ โ””โ”€โ”€ src/
72
+ โ”œโ”€โ”€ components/ # Reusable modular UI components
73
+ โ”‚ โ”œโ”€โ”€ Layout.tsx # Master HTML wrapper (<head>, <body>)
74
+ โ”‚ โ”œโ”€โ”€ Header.tsx # Navigation header
75
+ โ”‚ โ”œโ”€โ”€ Footer.tsx # Footer component
76
+ โ”‚ โ””โ”€โ”€ Counter.island.tsx # Interactive island component
77
+ โ””โ”€โ”€ pages/ # Page entrypoints
78
+ โ”œโ”€โ”€ index.tsx # -> dist/index.html
79
+ โ”œโ”€โ”€ about.tsx # -> dist/about.html
80
+ โ””โ”€โ”€ docs/
81
+ โ””โ”€โ”€ guide.tsx # -> dist/docs/guide.html
82
+ ```
83
+
84
+ ---
85
+
86
+ ## 3. Modular HTML with React
87
+
88
+ Eliminate repetitive HTML across your project by creating reusable layout components:
89
+
90
+ ```tsx
91
+ // src/components/Layout.tsx
92
+ import React, { ReactNode } from 'react';
93
+ import { Header } from './Header.js';
94
+ import { Footer } from './Footer.js';
95
+
96
+ export interface LayoutProps {
97
+ title?: string;
98
+ description?: string;
99
+ children: ReactNode;
100
+ }
101
+
102
+ export function Layout({
103
+ title = 'Default Title',
104
+ description = 'My static site',
105
+ children
106
+ }: LayoutProps) {
107
+ return (
108
+ <html lang="en">
109
+ <head>
110
+ <meta charSet="UTF-8" />
111
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
112
+ <title>{title}</title>
113
+ <meta name="description" content={description} />
114
+ <link rel="stylesheet" href="/styles.css" />
115
+ </head>
116
+ <body>
117
+ <Header />
118
+ <main className="container">{children}</main>
119
+ <Footer />
120
+ </body>
121
+ </html>
122
+ );
123
+ }
124
+ ```
125
+
126
+ Now, every page simply wraps its content without repeating `<head>`, stylesheets, or `<header>`/`<footer>`:
127
+
128
+ ```tsx
129
+ // src/pages/about.tsx
130
+ import React from 'react';
131
+ import { Layout } from '../components/Layout.js';
132
+
133
+ export const title = 'About Us';
134
+
135
+ export default function AboutPage() {
136
+ return (
137
+ <Layout title={title}>
138
+ <h1>About Our Project</h1>
139
+ <p>This entire page compiles into pure static HTML with 0 KB JavaScript!</p>
140
+ </Layout>
141
+ );
142
+ }
143
+ ```
144
+
145
+ ---
146
+
147
+ ## 4. Reactive Islands Architecture
148
+
149
+ When a component needs client-side state (`useState`, `useEffect`, event listeners):
150
+
151
+ ### Step 1: Wrap Component with `island()`
152
+
153
+ ```tsx
154
+ // src/components/Counter.island.tsx
155
+ import React, { useState } from 'react';
156
+ import { island } from 'react-html';
157
+
158
+ export interface CounterProps {
159
+ initialCount?: number;
160
+ step?: number;
161
+ }
162
+
163
+ function CounterComponent({ initialCount = 0, step = 1 }: CounterProps) {
164
+ const [count, setCount] = useState(initialCount);
165
+
166
+ return (
167
+ <div className="counter">
168
+ <p>Current: {count}</p>
169
+ <button onClick={() => setCount(c => c - step)}>- {step}</button>
170
+ <button onClick={() => setCount(c => c + step)}>+ {step}</button>
171
+ </div>
172
+ );
173
+ }
174
+
175
+ // Wrap with island helper providing Component, source path, and identifier
176
+ export const Counter = island(CounterComponent, import.meta.url, 'Counter');
177
+ export default Counter;
178
+ ```
179
+
180
+ ### Step 2: Use in Any Page
181
+
182
+ ```tsx
183
+ // src/pages/index.tsx
184
+ import React from 'react';
185
+ import { Layout } from '../components/Layout.js';
186
+ import { Counter } from '../components/Counter.island.js';
187
+
188
+ export default function HomePage() {
189
+ return (
190
+ <Layout title="Home">
191
+ <h1>Interactive Page</h1>
192
+ {/* Pre-rendered to HTML for instant paint, then hydrated with tiny JS */}
193
+ <Counter initialCount={10} step={2} />
194
+ </Layout>
195
+ );
196
+ }
197
+ ```
198
+
199
+ ### What Happens Behind the Scenes:
200
+ 1. **Server Phase**: The island is pre-rendered with `renderToString` and placed inside a container `<div data-island="Counter" data-props="...">`.
201
+ 2. **Bundler Phase**: `esbuild` extracts and bundles only `CounterComponent` into `dist/assets/islands/Counter.js`.
202
+ 3. **Injection Phase**: `<script type="module" src="/assets/islands/Counter.js"></script>` is injected right before `</body>`.
203
+ 4. **Client Hydration**: The script queries `[data-island="Counter"]` and attaches listeners using React 19's `hydrateRoot`.
204
+
205
+ ---
206
+
207
+ ## 5. Hydration Directives
208
+
209
+ Fine-tune client performance using the `client` prop:
210
+
211
+ | Directive | Code Example | When It Hydrates |
212
+ | :--- | :--- | :--- |
213
+ | `load` *(default)* | `<Counter client="load" />` | Immediately upon `DOMContentLoaded`. Ideal for primary UI. |
214
+ | `idle` | `<Counter client="idle" />` | During browser idle time via `requestIdleCallback`. Ideal for background widgets. |
215
+ | `visible` | `<Counter client="visible" />` | When scrolled into view via `IntersectionObserver`. Ideal for below-the-fold content. |
216
+
217
+ ---
218
+
219
+ ## 6. CLI Commands & Options
220
+
221
+ ```bash
222
+ # Build static site to dist/
223
+ react-html build
224
+
225
+ # Customize directories
226
+ react-html build --pages src/pages --out dist --root .
227
+
228
+ # Start local preview server with auto-rebuild on file changes
229
+ react-html dev --port 3000 --host localhost
230
+
231
+ # Terminal UI documentation viewer
232
+ react-html docs
233
+ react-html docs --all
234
+ react-html docs islands
235
+ ```
236
+
237
+ ---
238
+
239
+ ## 7. Programmatic API Reference
240
+
241
+ You can import and trigger `react-html` within custom build scripts or Node.js services:
242
+
243
+ ```ts
244
+ import { build, renderPageToHtml, createDevServer } from 'react-html';
245
+
246
+ // 1. Run static build
247
+ const result = await build({
248
+ root: process.cwd(),
249
+ pagesDir: 'src/pages',
250
+ outDir: 'dist',
251
+ minify: true
252
+ });
253
+ console.log(`Generated ${result.pages.length} pages.`);
254
+
255
+ // 2. Programmatic dev server
256
+ const server = await createDevServer({
257
+ port: 8080,
258
+ host: '127.0.0.1'
259
+ });
260
+ ```
261
+
262
+ ---
263
+
264
+ ## 8. Server App Integration (Express, Fastify, Node HTTP)
265
+
266
+ You can import and use `react-html` directly inside your backend server application:
267
+
268
+ ```ts
269
+ import express from 'express';
270
+ import { createEngine } from 'react-html';
271
+ // or: import { createEngine } from 'react-html/server';
272
+
273
+ const app = express();
274
+
275
+ const engine = createEngine({
276
+ pagesDir: 'src/pages',
277
+ distDir: 'dist',
278
+ // Automatically detects process.env.NODE_ENV === 'production'
279
+ });
280
+
281
+ // 1. Connect / Express Middleware
282
+ // In Production: finds and serves pre-built static HTML from dist/
283
+ // In Development: dynamically rebuilds TSX on the fly and returns the fresh HTML string!
284
+ app.use(engine.middleware);
285
+
286
+ // 2. Programmatic Route Rendering
287
+ app.get('/dashboard', async (req, res) => {
288
+ const html = await engine.render('dashboard', { user: req.user });
289
+ res.setHeader('Content-Type', 'text/html; charset=utf-8');
290
+ res.send(html);
291
+ });
292
+
293
+ // 3. Native Node HTTP Server
294
+ import http from 'node:http';
295
+ const server = http.createServer(engine.handle);
296
+ server.listen(3000);
297
+ ```
298
+
299
+ ### Environment Behavior:
300
+ - **`process.env.NODE_ENV === 'production'`**:
301
+ - Automatically searches for pre-built `.html` files in `distDir` (`dist/index.html`, `dist/about.html`).
302
+ - Streams them immediately to clients with 0 rebuild overhead.
303
+ - Serves static assets (`dist/assets/islands/*.js`, `dist/styles.css`).
304
+ - **`process.env.NODE_ENV !== 'production'` (Development)**:
305
+ - Dynamically rebuilds the corresponding `.tsx` page on each request.
306
+ - Bundles any reactive islands on-the-fly.
307
+ - Returns the fresh HTML string directly in the responseโ€”code edits in `src/pages` or `src/components` are reflected instantly on reload without server restarts!
308
+
309
+ ---
310
+
311
+ ## 9. Best Practices & Troubleshooting
312
+
313
+ ### Preventing Hydration Mismatches (React Error #418)
314
+ - **Do not read browser globals during initial render**: Avoid `window.innerWidth` or `localStorage.getItem()` directly in the component body. Read them inside a `useEffect()`.
315
+ - **Props consistency**: Ensure initial props passed from the page match what the component expects.
316
+ - **Protected formatting**: `react-html` automatically preserves the exact inner markup of islands so whitespace insertion does not invalidate React's DOM reconciliation.
317
+
package/README.md CHANGED
@@ -1,3 +1,216 @@
1
- # Temporary Holding Version
1
+ # react-html โš›๏ธ โžก๏ธ ๐Ÿ“„
2
+
3
+ A blazing-fast engine to convert React/JSX components into **pure, semantic HTML** with selective compilation of interactive components into **micro JavaScript islands**.
4
+
5
+ Write DRY, modular HTML using React components without shipping any React runtime or JavaScript to the client by default.
6
+
7
+ ---
8
+
9
+ ## ๐ŸŒŸ Why react-html?
10
+
11
+ - **Zero-JS by Default**: Static pages are rendered to 100% pure HTML. No client-side React runtime, no `<script>` tags, and 0 KB JavaScript overhead.
12
+ - **Modular & DRY**: Stop duplicating headers, footers, meta tags, and layouts. Build reusable components (`<Layout>`, `<Header>`, `<Card>`, `<Footer>`) using familiar React JSX syntax.
13
+ - **Selective Reactivity (Islands Architecture)**: When a component needs client-side interactivity (counters, modals, tabs, forms), the engine bundles only that component into a standalone, micro ESM script using `esbuild`.
14
+ - **Fast Build Pipeline**: Powered by `esbuild` for instantaneous static site generation and sub-100ms builds.
15
+ - **Node.js Native**: Runs strictly on standard Node.js (v20+) with npm.
16
+
17
+ ---
18
+
19
+ ## ๐Ÿš€ Quick Start
20
+
21
+ ### Installation
22
+
23
+ ```bash
24
+ npm install react-html
25
+ ```
26
+
27
+ Or install globally / link locally:
28
+
29
+ ```bash
30
+ npm link
31
+ ```
32
+
33
+ ### CLI Usage
34
+
35
+ ```bash
36
+ # Build static site to dist/
37
+ react-html build
38
+
39
+ # Build with custom pages or output directory
40
+ react-html build --pages src/pages --out dist
41
+
42
+ # Start dev server with watch & live recompile
43
+ react-html dev --port 3000
44
+ ```
45
+
46
+ ---
47
+
48
+ ## ๐Ÿ“– How It Works
49
+
50
+ ### 1. Pure Modular HTML (Zero JavaScript)
51
+
52
+ Create your reusable layout and page components using standard JSX:
53
+
54
+ ```tsx
55
+ // src/components/Layout.tsx
56
+ import React, { ReactNode } from 'react';
57
+
58
+ export function Layout({ title, children }: { title: string; children: ReactNode }) {
59
+ return (
60
+ <html lang="en">
61
+ <head>
62
+ <meta charSet="UTF-8" />
63
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
64
+ <title>{title}</title>
65
+ <link rel="stylesheet" href="/styles.css" />
66
+ </head>
67
+ <body>
68
+ <header>
69
+ <h1>My Modular Site</h1>
70
+ </header>
71
+ <main>{children}</main>
72
+ </body>
73
+ </html>
74
+ );
75
+ }
76
+ ```
77
+
78
+ ```tsx
79
+ // src/pages/about.tsx
80
+ import React from 'react';
81
+ import { Layout } from '../components/Layout.js';
82
+
83
+ export default function AboutPage() {
84
+ return (
85
+ <Layout title="About Us">
86
+ <h2>About Our Project</h2>
87
+ <p>This entire page compiles into pure static HTML with 0 KB JavaScript!</p>
88
+ </Layout>
89
+ );
90
+ }
91
+ ```
92
+
93
+ **Output in `dist/about.html`:**
94
+ ```html
95
+ <!DOCTYPE html>
96
+ <html lang="en">
97
+ <head>
98
+ <meta charSet="UTF-8"/>
99
+ <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
100
+ <title>About Us</title>
101
+ <link rel="stylesheet" href="/styles.css"/>
102
+ </head>
103
+ <body>
104
+ <header>
105
+ <h1>My Modular Site</h1>
106
+ </header>
107
+ <main>
108
+ <h2>About Our Project</h2>
109
+ <p>This entire page compiles into pure static HTML with 0 KB JavaScript!</p>
110
+ </main>
111
+ </body>
112
+ </html>
113
+ ```
114
+
115
+ ---
116
+
117
+ ### 2. Reactive Components (Islands Architecture)
118
+
119
+ When a component needs client-side state and interactivity, wrap it with `island()`:
120
+
121
+ ```tsx
122
+ // src/components/Counter.island.tsx
123
+ import React, { useState } from 'react';
124
+ import { island } from 'react-html';
125
+
126
+ export interface CounterProps {
127
+ initial?: number;
128
+ }
129
+
130
+ function CounterComponent({ initial = 0 }: CounterProps) {
131
+ const [count, setCount] = useState(initial);
132
+
133
+ return (
134
+ <div className="counter">
135
+ <button onClick={() => setCount(c => c - 1)}>-</button>
136
+ <span>Count: {count}</span>
137
+ <button onClick={() => setCount(c => c + 1)}>+</button>
138
+ </div>
139
+ );
140
+ }
141
+
142
+ // Export the island with its unique name and source path
143
+ export const Counter = island(CounterComponent, import.meta.url, 'Counter');
144
+ export default Counter;
145
+ ```
146
+
147
+ Now import and use it in any page just like a normal React component:
148
+
149
+ ```tsx
150
+ // src/pages/index.tsx
151
+ import React from 'react';
152
+ import { Layout } from '../components/Layout.js';
153
+ import { Counter } from '../components/Counter.island.js';
154
+
155
+ export default function HomePage() {
156
+ return (
157
+ <Layout title="Home">
158
+ <h2>Welcome!</h2>
159
+ {/* Pre-rendered to HTML for instant paint, then hydrated with tiny JS */}
160
+ <Counter initial={10} />
161
+ </Layout>
162
+ );
163
+ }
164
+ ```
165
+
166
+ **What the engine does:**
167
+ 1. Renders the initial static markup during SSR for instant paint.
168
+ 2. Compiles a dedicated micro-bundle `dist/assets/islands/Counter.js`.
169
+ 3. Injects `<script type="module" src="/assets/islands/Counter.js"></script>` into `index.html`.
170
+ 4. Hydrates only the island element in-place using React 19's `hydrateRoot`.
171
+
172
+ ---
173
+
174
+ ## ๐Ÿ› ๏ธ Hydration Directives
175
+
176
+ `react-html` supports client loading directives to maximize performance:
177
+
178
+ | Directive | Syntax | Behavior |
179
+ | :--- | :--- | :--- |
180
+ | `load` (default) | `<Counter client="load" />` | Hydrates immediately on DOM ready |
181
+ | `idle` | `<Counter client="idle" />` | Hydrates during browser idle time (`requestIdleCallback`) |
182
+ | `visible` | `<Counter client="visible" />` | Hydrates when scrolled into view (`IntersectionObserver`) |
183
+
184
+ ---
185
+
186
+ ## ๐Ÿ’ป Programmatic API
187
+
188
+ You can also run `react-html` programmatically from your Node.js scripts:
189
+
190
+ ```ts
191
+ import { build } from 'react-html';
192
+
193
+ const result = await build({
194
+ root: process.cwd(),
195
+ pagesDir: 'src/pages',
196
+ outDir: 'dist',
197
+ minify: true
198
+ });
199
+
200
+ console.log(`Compiled ${result.pages.length} pages and ${result.islands.length} reactive islands.`);
201
+ ```
202
+
203
+ ---
204
+
205
+ ## ๐Ÿงช Testing
206
+
207
+ Run the automated test suite powered by Node.js test runner:
208
+
209
+ ```bash
210
+ npm test
211
+ ```
212
+
213
+ ## ๐Ÿ“„ License
214
+
215
+ MIT
2
216
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ import { runCli } from '../dist/cli/index.js';
3
+
4
+ runCli().catch((err) => {
5
+ console.error('[react-html] Fatal error:', err);
6
+ process.exit(1);
7
+ });
8
+