react-bun-ssr 0.3.0 → 0.3.1

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/README.md CHANGED
@@ -57,9 +57,15 @@ For the full setup walkthrough, read the installation guide:
57
57
  `rbssr init` scaffolds a small Bun-first SSR app:
58
58
 
59
59
  ```text
60
+ package.json
61
+ tsconfig.json
62
+ .gitignore
60
63
  app/
61
64
  root.tsx
65
+ root.module.css
62
66
  middleware.ts
67
+ public/
68
+ favicon.svg
63
69
  routes/
64
70
  index.tsx
65
71
  api/
@@ -67,8 +73,13 @@ app/
67
73
  rbssr.config.ts
68
74
  ```
69
75
 
76
+ - `package.json`: Bun scripts and framework/runtime dependencies
77
+ - `tsconfig.json`: starter TypeScript config for Bun + JSX
78
+ - `.gitignore`: minimal app-level ignore rules
70
79
  - `app/root.tsx`: document shell and top-level layout
80
+ - `app/root.module.css`: starter CSS Module for layout and base presentation
71
81
  - `app/middleware.ts`: global request pipeline hook
82
+ - `app/public/favicon.svg`: starter public asset
72
83
  - `app/routes/index.tsx`: first SSR page route
73
84
  - `app/routes/api/health.ts`: first API route
74
85
  - `rbssr.config.ts`: runtime configuration entrypoint
@@ -6,6 +6,23 @@ interface ScaffoldFile {
6
6
  content: string;
7
7
  }
8
8
 
9
+ interface FrameworkPackageManifest {
10
+ version?: string;
11
+ devDependencies?: Record<string, string>;
12
+ }
13
+
14
+ const DEFAULT_FRAMEWORK_VERSION = "0.0.0";
15
+ const DEFAULT_TYPESCRIPT_VERSION = "^5";
16
+ const DEFAULT_BUN_TYPES_VERSION = "latest";
17
+ const DEFAULT_REACT_TYPES_VERSION = "^19";
18
+ const FAVICON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96">
19
+ <rect width="96" height="96" rx="20" fill="#111827"/>
20
+ <path d="M25 28h20c13.807 0 25 11.193 25 25S58.807 78 45 78H25V28Zm18 40c8.837 0 16-7.163 16-16s-7.163-16-16-16h-8v32h8Z" fill="#f9fafb"/>
21
+ </svg>
22
+ `;
23
+
24
+ let frameworkPackageManifestPromise: Promise<FrameworkPackageManifest> | null = null;
25
+
9
26
  async function writeIfMissing(filePath: string, content: string, force: boolean): Promise<void> {
10
27
  if (!force && await existsPath(filePath)) {
11
28
  return;
@@ -14,8 +31,115 @@ async function writeIfMissing(filePath: string, content: string, force: boolean)
14
31
  await writeText(filePath, content);
15
32
  }
16
33
 
17
- function templateFiles(cwd: string): ScaffoldFile[] {
34
+ function getFrameworkPackageManifest(): Promise<FrameworkPackageManifest> {
35
+ if (!frameworkPackageManifestPromise) {
36
+ const packageJsonPath = path.resolve(import.meta.dir, "../../package.json");
37
+ frameworkPackageManifestPromise = Bun.file(packageJsonPath).json() as Promise<FrameworkPackageManifest>;
38
+ }
39
+
40
+ return frameworkPackageManifestPromise;
41
+ }
42
+
43
+ function normalizePackageName(cwd: string): string {
44
+ const baseName = path.basename(path.resolve(cwd));
45
+ const normalized = baseName
46
+ .toLowerCase()
47
+ .replace(/[^a-z0-9._-]+/g, "-")
48
+ .replace(/[._-]{2,}/g, "-")
49
+ .replace(/^[._-]+|[._-]+$/g, "");
50
+
51
+ return normalized || "rbssr-app";
52
+ }
53
+
54
+ function createPackageJsonContent(options: {
55
+ cwd: string;
56
+ frameworkVersion: string;
57
+ typescriptVersion: string;
58
+ bunTypesVersion: string;
59
+ reactTypesVersion: string;
60
+ reactDomTypesVersion: string;
61
+ }): string {
62
+ const packageJson = {
63
+ name: normalizePackageName(options.cwd),
64
+ version: "0.0.0",
65
+ private: true,
66
+ type: "module",
67
+ scripts: {
68
+ dev: "rbssr dev",
69
+ build: "rbssr build",
70
+ start: "rbssr start",
71
+ typecheck: "bunx tsc --noEmit",
72
+ },
73
+ dependencies: {
74
+ "react-bun-ssr": options.frameworkVersion,
75
+ react: "^19",
76
+ "react-dom": "^19",
77
+ },
78
+ devDependencies: {
79
+ "@types/react": options.reactTypesVersion,
80
+ "@types/react-dom": options.reactDomTypesVersion,
81
+ "bun-types": options.bunTypesVersion,
82
+ typescript: options.typescriptVersion,
83
+ },
84
+ };
85
+
86
+ return `${JSON.stringify(packageJson, null, 2)}\n`;
87
+ }
88
+
89
+ function createTsconfigContent(): string {
90
+ const tsconfig = {
91
+ compilerOptions: {
92
+ target: "ESNext",
93
+ module: "Preserve",
94
+ moduleResolution: "Bundler",
95
+ jsx: "react-jsx",
96
+ strict: true,
97
+ types: ["bun-types"],
98
+ },
99
+ include: ["app", "rbssr.config.ts"],
100
+ };
101
+
102
+ return `${JSON.stringify(tsconfig, null, 2)}\n`;
103
+ }
104
+
105
+ function createGitignoreContent(): string {
106
+ return `node_modules
107
+ dist
108
+ .rbssr
109
+ .env
110
+ .env.local
111
+ .DS_Store
112
+ `;
113
+ }
114
+
115
+ async function templateFiles(cwd: string): Promise<ScaffoldFile[]> {
116
+ const frameworkPackage = await getFrameworkPackageManifest();
117
+ const frameworkVersion = frameworkPackage.version ?? DEFAULT_FRAMEWORK_VERSION;
118
+ const typescriptVersion = frameworkPackage.devDependencies?.typescript ?? DEFAULT_TYPESCRIPT_VERSION;
119
+ const bunTypesVersion = frameworkPackage.devDependencies?.["bun-types"] ?? DEFAULT_BUN_TYPES_VERSION;
120
+ const reactTypesVersion = frameworkPackage.devDependencies?.["@types/react"] ?? DEFAULT_REACT_TYPES_VERSION;
121
+ const reactDomTypesVersion = frameworkPackage.devDependencies?.["@types/react-dom"] ?? DEFAULT_REACT_TYPES_VERSION;
122
+
18
123
  return [
124
+ {
125
+ filePath: path.join(cwd, "package.json"),
126
+ content: createPackageJsonContent({
127
+ cwd,
128
+ frameworkVersion,
129
+ typescriptVersion,
130
+ bunTypesVersion,
131
+ reactTypesVersion,
132
+ reactDomTypesVersion,
133
+ }),
134
+ },
135
+ {
136
+ filePath: path.join(cwd, "tsconfig.json"),
137
+ content: createTsconfigContent(),
138
+ },
139
+ {
140
+ filePath: path.join(cwd, ".gitignore"),
141
+ content: createGitignoreContent(),
142
+ },
19
143
  {
20
144
  filePath: path.join(cwd, "rbssr.config.ts"),
21
145
  content: `import { defineConfig } from "react-bun-ssr";
@@ -29,14 +153,17 @@ export default defineConfig({
29
153
  {
30
154
  filePath: path.join(cwd, "app/root.tsx"),
31
155
  content: `import { Outlet } from "react-bun-ssr/route";
156
+ import styles from "./root.module.css";
32
157
 
33
158
  export default function RootLayout() {
34
159
  return (
35
- <main className="shell">
36
- <header className="top">
160
+ <main className={styles.shell}>
161
+ <header className={styles.top}>
37
162
  <h1>react-bun-ssr</h1>
38
163
  </header>
39
- <Outlet />
164
+ <section className={styles.content}>
165
+ <Outlet />
166
+ </section>
40
167
  </main>
41
168
  );
42
169
  }
@@ -44,6 +171,53 @@ export default function RootLayout() {
44
171
  export function head() {
45
172
  return <title>react-bun-ssr app</title>;
46
173
  }
174
+ `,
175
+ },
176
+ {
177
+ filePath: path.join(cwd, "app/root.module.css"),
178
+ content: `:global(*) {
179
+ box-sizing: border-box;
180
+ }
181
+
182
+ :global(html) {
183
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
184
+ background: linear-gradient(180deg, #f8fafc 0%, #e2e8f0 100%);
185
+ color: #0f172a;
186
+ }
187
+
188
+ :global(body) {
189
+ margin: 0;
190
+ }
191
+
192
+ .shell {
193
+ min-height: 100vh;
194
+ width: min(100%, 72rem);
195
+ margin: 0 auto;
196
+ padding: 3rem 1.5rem 4rem;
197
+ }
198
+
199
+ .top {
200
+ display: flex;
201
+ align-items: center;
202
+ justify-content: space-between;
203
+ margin-bottom: 2rem;
204
+ }
205
+
206
+ .top h1 {
207
+ margin: 0;
208
+ font-size: clamp(2rem, 5vw, 3.5rem);
209
+ line-height: 1;
210
+ letter-spacing: -0.04em;
211
+ }
212
+
213
+ .content {
214
+ padding: 1.5rem;
215
+ border: 1px solid rgba(15, 23, 42, 0.08);
216
+ border-radius: 1.5rem;
217
+ background: rgba(255, 255, 255, 0.84);
218
+ box-shadow: 0 24px 60px rgba(15, 23, 42, 0.12);
219
+ backdrop-filter: blur(18px);
220
+ }
47
221
  `,
48
222
  },
49
223
  {
@@ -87,11 +261,15 @@ export const middleware: Middleware = async (ctx, next) => {
87
261
  };
88
262
  `,
89
263
  },
264
+ {
265
+ filePath: path.join(cwd, "app/public/favicon.svg"),
266
+ content: FAVICON_SVG,
267
+ },
90
268
  ];
91
269
  }
92
270
 
93
271
  export async function scaffoldApp(cwd: string, options: { force: boolean }): Promise<void> {
94
- for (const file of templateFiles(cwd)) {
272
+ for (const file of await templateFiles(cwd)) {
95
273
  await writeIfMissing(file.filePath, file.content, options.force);
96
274
  }
97
275
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-bun-ssr",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "sideEffects": false,