@webjsdev/cli 0.10.26 → 0.10.28
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 +1 -1
- package/bin/webjs.js +5 -10
- package/lib/create.js +24 -143
- package/lib/runtime-rewrite.js +7 -3
- package/package.json +1 -1
- package/templates/AGENTS.md +5 -19
package/README.md
CHANGED
|
@@ -33,7 +33,7 @@ npx @webjsdev/cli create my-app
|
|
|
33
33
|
cd my-app && npm run dev
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
`webjs create`
|
|
36
|
+
Both `webjs create` and `create-webjs-app` auto-install dependencies in the new directory using your detected package manager (npm / pnpm / yarn / bun). Pass `--no-install` to opt out.
|
|
37
37
|
|
|
38
38
|
## Commands
|
|
39
39
|
|
package/bin/webjs.js
CHANGED
|
@@ -50,12 +50,12 @@ const USAGE = `webjs commands:
|
|
|
50
50
|
webjs doctor Verify project health (Node, tsconfig, env, vendor pins, importmap coherence, @webjsdev versions, git hook, page/layout elision)
|
|
51
51
|
webjs types Generate .webjs/routes.d.ts (typed Route union + per-route params)
|
|
52
52
|
webjs typecheck [tsc args...] Type-check the app with the project's tsc --noEmit (non-zero on errors)
|
|
53
|
-
webjs create <name> [--template full-stack|api|saas] [--db sqlite|postgres] [--runtime node|bun] [--
|
|
53
|
+
webjs create <name> [--template full-stack|api|saas] [--db sqlite|postgres] [--runtime node|bun] [--no-install] Scaffold a new webjs app
|
|
54
54
|
(only 3 templates exist. default: full-stack, Drizzle, --db sqlite, --runtime node)
|
|
55
55
|
--runtime bun emits a Bun-flavored app (bun.lock, bun Dockerfile/CI, bun docs);
|
|
56
56
|
also auto-detected when run via "bun create webjs".
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
Auto-runs the detected package manager's install in the new dir
|
|
58
|
+
unless --no-install is passed.
|
|
59
59
|
webjs db generate Generate a SQL migration from the schema (drizzle-kit generate)
|
|
60
60
|
webjs db migrate Apply pending migrations (drizzle-kit migrate)
|
|
61
61
|
webjs db push Push the schema straight to the dev DB (drizzle-kit push)
|
|
@@ -521,11 +521,7 @@ files.
|
|
|
521
521
|
Full docs: https://docs.webjs.com`);
|
|
522
522
|
process.exit(1);
|
|
523
523
|
}
|
|
524
|
-
// Install policy (#682). Default per runtime: Node installs (needs
|
|
525
|
-
// node_modules to run); Bun skips (zero-install, `bun run dev` resolves
|
|
526
|
-
// on the fly). `--install` / `--no-install` override either way.
|
|
527
524
|
const noInstall = rest.includes('--no-install');
|
|
528
|
-
const explicitInstall = rest.includes('--install');
|
|
529
525
|
// --db picks the database dialect: sqlite (default) or postgres.
|
|
530
526
|
const db = flag(rest, '--db', 'sqlite');
|
|
531
527
|
// --runtime picks the target runtime: node (default) or bun. Orthogonal
|
|
@@ -536,9 +532,8 @@ Full docs: https://docs.webjs.com`);
|
|
|
536
532
|
console.error(`Error: unknown --runtime '${runtime}'. Only node / bun are supported.`);
|
|
537
533
|
process.exit(1);
|
|
538
534
|
}
|
|
539
|
-
const { scaffoldApp
|
|
540
|
-
|
|
541
|
-
await scaffoldApp(name, process.cwd(), { template, db, runtime, install });
|
|
535
|
+
const { scaffoldApp } = await import('../lib/create.js');
|
|
536
|
+
await scaffoldApp(name, process.cwd(), { template, db, runtime, install: !noInstall });
|
|
542
537
|
break;
|
|
543
538
|
}
|
|
544
539
|
case 'vendor': {
|
package/lib/create.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
import { mkdir, writeFile, readFile, cp } from 'node:fs/promises';
|
|
15
15
|
import { join, resolve, dirname } from 'node:path';
|
|
16
16
|
import { fileURLToPath } from 'node:url';
|
|
17
|
-
import { existsSync
|
|
17
|
+
import { existsSync } from 'node:fs';
|
|
18
18
|
import { createRequire } from 'node:module';
|
|
19
19
|
import { spawnSync } from 'node:child_process';
|
|
20
20
|
import { bunifyProse, bunifyDockerfile, bunifyCompose, bunifyCi } from './runtime-rewrite.js';
|
|
@@ -35,86 +35,6 @@ function detectPackageManager() {
|
|
|
35
35
|
return 'npm';
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
/**
|
|
39
|
-
* Decide whether `webjs create` runs the post-scaffold install, per target
|
|
40
|
-
* runtime (#682). Node installs by default (it needs `node_modules` to run);
|
|
41
|
-
* Bun SKIPS by default (zero-install: `bun run dev` resolves deps on the fly,
|
|
42
|
-
* #675). Under Bun zero-install webjs pins a declared dep to its package.json
|
|
43
|
-
* version via the #685/#698 onLoad rewrite (a caret range now resolves the
|
|
44
|
-
* highest match, not absolute latest), so `bun install` is the path to a frozen
|
|
45
|
-
* lockfile, not a correctness fix. Explicit flags win: `--install` forces it
|
|
46
|
-
* on, `--no-install` forces it off. The CLI entry points call this and pass an
|
|
47
|
-
* explicit boolean to `scaffoldApp`, so the library default (no install unless
|
|
48
|
-
* `install: true`) is unchanged for programmatic callers.
|
|
49
|
-
*
|
|
50
|
-
* @param {{ runtime?: string, explicitInstall?: boolean, noInstall?: boolean }} [o]
|
|
51
|
-
* @returns {boolean}
|
|
52
|
-
*/
|
|
53
|
-
export function resolveCreateInstall({ runtime, explicitInstall, noInstall } = {}) {
|
|
54
|
-
if (explicitInstall) return true;
|
|
55
|
-
if (noInstall) return false;
|
|
56
|
-
const isBun = runtime === 'bun' || (!runtime && detectPackageManager() === 'bun');
|
|
57
|
-
return !isBun;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Read the EXACT version of `@webjsdev/<pkg>` the scaffolding CLI ships with.
|
|
62
|
-
* `webjsdevRange` carets over this for the generated `package.json` (#700), so a
|
|
63
|
-
* fresh app tracks the line the CLI shipped. Walks the `require.resolve` node_modules search paths
|
|
64
|
-
* and fs-reads `<pkg>/package.json` directly: `@webjsdev/server` (and `ui`) hide
|
|
65
|
-
* `./package.json` behind `exports`, so a bare `require('<pkg>/package.json')`
|
|
66
|
-
* fails (same constraint #687 hit). Falls back to `'latest'` when the package is
|
|
67
|
-
* not resolvable (defensive; the CLI's own dependency closure is normally
|
|
68
|
-
* present), which keeps the scaffold working rather than emitting a bad pin.
|
|
69
|
-
* @param {string} pkg e.g. 'cli', 'core', 'server'
|
|
70
|
-
* @returns {string} an exact version, or 'latest'
|
|
71
|
-
*/
|
|
72
|
-
function webjsdevVersion(pkg) {
|
|
73
|
-
const req = createRequire(import.meta.url);
|
|
74
|
-
for (const base of (req.resolve.paths(`@webjsdev/${pkg}`) || [])) {
|
|
75
|
-
const pj = join(base, '@webjsdev', pkg, 'package.json');
|
|
76
|
-
if (existsSync(pj)) {
|
|
77
|
-
try {
|
|
78
|
-
const v = JSON.parse(readFileSync(pj, 'utf8')).version;
|
|
79
|
-
if (v) return v;
|
|
80
|
-
} catch { /* unreadable; keep looking, then fall back */ }
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return 'latest';
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* The `@webjsdev/<pkg>` specifier for the generated `package.json` (#700): a
|
|
88
|
-
* caret range over the version the scaffolding CLI ships with, so a fresh app
|
|
89
|
-
* picks up patch updates the way an npm user expects (a `^0.x` caret stays
|
|
90
|
-
* within the minor). Bun zero-install resolves a normal caret range correctly
|
|
91
|
-
* since #698, so this no longer diverges from npm. Falls back to `'latest'` when
|
|
92
|
-
* the version is not resolvable (keeps `^latest` from ever being emitted).
|
|
93
|
-
* @param {string} pkg e.g. 'cli', 'core', 'server'
|
|
94
|
-
* @returns {string}
|
|
95
|
-
*/
|
|
96
|
-
function webjsdevRange(pkg) {
|
|
97
|
-
const v = webjsdevVersion(pkg);
|
|
98
|
-
return v === 'latest' ? 'latest' : '^' + v;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Third-party dep specifiers the scaffold ships (#700). These are template deps
|
|
103
|
-
* the CLI does NOT itself depend on, so they cannot be read from the CLI's
|
|
104
|
-
* closure (unlike `@webjsdev/*`). Since #698, Bun zero-install resolves a normal
|
|
105
|
-
* caret range correctly (highest match, not absolute latest), so `pg` is an
|
|
106
|
-
* idiomatic `^` range. Drizzle is PINNED to an exact RC: its 1.0 line is a
|
|
107
|
-
* PRERELEASE (`1.0.0-rc.3`), and Bun zero-install ENOENTs on a caret-prerelease
|
|
108
|
-
* inline specifier (`drizzle-orm@^1.0.0-rc.3`, verified on Bun 1.3.14) while the
|
|
109
|
-
* exact prerelease resolves, so drizzle must stay exact until the 1.0 stable
|
|
110
|
-
* ships. Refresh on a deliberate bump.
|
|
111
|
-
*/
|
|
112
|
-
const SCAFFOLD_DEP_VERSIONS = {
|
|
113
|
-
'drizzle-orm': '1.0.0-rc.3',
|
|
114
|
-
'drizzle-kit': '1.0.0-rc.3',
|
|
115
|
-
pg: '^8.22.0',
|
|
116
|
-
};
|
|
117
|
-
|
|
118
38
|
/**
|
|
119
39
|
* Run `<pm> install` inside the scaffolded app. Returns true on success.
|
|
120
40
|
* Inherits stdio so the user sees the install progress live. Caller decides
|
|
@@ -353,10 +273,6 @@ export async function scaffoldApp(name, cwd, opts = {}) {
|
|
|
353
273
|
throw new Error(`Unknown --runtime '${runtime}'. Only ${VALID_RUNTIMES.join(' / ')} are supported.`);
|
|
354
274
|
}
|
|
355
275
|
const isBun = runtime === 'bun';
|
|
356
|
-
// Zero-install Bun entry (#675): the app-local `webjs-bun.mjs` bootstrap, run
|
|
357
|
-
// under `bun --bun`, so the server resolves the CLI + deps via Bun auto-install
|
|
358
|
-
// (no `bun install` required). App-local so it is resolvable with no node_modules.
|
|
359
|
-
const bunBoot = 'bun --bun webjs-bun.mjs';
|
|
360
276
|
const appDir = join(cwd, name);
|
|
361
277
|
if (existsSync(appDir)) {
|
|
362
278
|
console.error(`Error: directory '${name}' already exists.`);
|
|
@@ -402,19 +318,18 @@ export async function scaffoldApp(name, cwd, opts = {}) {
|
|
|
402
318
|
// so `npm run start` (a thin alias) behaves identically. Drizzle has no
|
|
403
319
|
// codegen, so there is no dev `before` step.
|
|
404
320
|
//
|
|
405
|
-
// Bun runtime (#541
|
|
406
|
-
//
|
|
407
|
-
// `webjs` bin's `#!/usr/bin/env node` shebang (without it `bun run dev`
|
|
321
|
+
// Bun runtime (#541): the long-running server scripts (`dev` / `start`)
|
|
322
|
+
// are prefixed `bun --bun` so the app SERVES on Bun. The `--bun` overrides
|
|
323
|
+
// the `webjs` bin's `#!/usr/bin/env node` shebang (without it `bun run dev`
|
|
408
324
|
// would exec webjs under Node, silently running the "bun" app on Node).
|
|
409
|
-
//
|
|
410
|
-
//
|
|
411
|
-
//
|
|
412
|
-
// with NO `bun install` (install becomes optional, for editor types /
|
|
413
|
-
// offline). The runtime-neutral tooling scripts (test / check / typecheck
|
|
325
|
+
// Baking it into the script body means a plain `bun run dev` (or even
|
|
326
|
+
// `npm run dev`) starts on Bun, so a user never has to remember the flag.
|
|
327
|
+
// The runtime-neutral tooling scripts below (test / db / check / typecheck
|
|
414
328
|
// / doctor) stay plain `webjs ...`: they spawn node tooling (`node --test`,
|
|
415
|
-
// tsc)
|
|
416
|
-
|
|
417
|
-
|
|
329
|
+
// drizzle-kit, tsc) and forcing `--bun` there buys nothing (and `webjs
|
|
330
|
+
// test` shells `node --test`, which a `bun --test` would not be).
|
|
331
|
+
dev: isBun ? 'bun --bun webjs dev' : 'webjs dev',
|
|
332
|
+
start: isBun ? 'bun --bun webjs start' : 'webjs start',
|
|
418
333
|
test: 'webjs test',
|
|
419
334
|
'test:server': 'webjs test --server',
|
|
420
335
|
'test:browser': 'webjs test --browser',
|
|
@@ -425,31 +340,25 @@ export async function scaffoldApp(name, cwd, opts = {}) {
|
|
|
425
340
|
// vendor pins, @webjsdev versions, git hook). Local tool, NOT a CI gate
|
|
426
341
|
// (its env-drift + network pin-freshness checks would make CI flaky).
|
|
427
342
|
doctor: 'webjs doctor',
|
|
428
|
-
'db:generate':
|
|
429
|
-
'db:migrate':
|
|
430
|
-
'db:push':
|
|
431
|
-
'db:studio':
|
|
432
|
-
'db:seed':
|
|
343
|
+
'db:generate': 'webjs db generate',
|
|
344
|
+
'db:migrate': 'webjs db migrate',
|
|
345
|
+
'db:push': 'webjs db push',
|
|
346
|
+
'db:studio': 'webjs db studio',
|
|
347
|
+
'db:seed': 'webjs db seed',
|
|
433
348
|
},
|
|
434
349
|
dependencies: {
|
|
435
350
|
// Drizzle ORM (no codegen, no engine binary). Pinned to the 1.0 line
|
|
436
351
|
// for relations v2. SQLite needs NO driver dependency: the connection
|
|
437
352
|
// uses the built-in node:sqlite (Node) / bun:sqlite (Bun) via Drizzle's
|
|
438
353
|
// node-sqlite / bun-sqlite adapters. Postgres still needs the pg driver.
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
'
|
|
444
|
-
...(dialect === 'postgres' ? { pg: SCAFFOLD_DEP_VERSIONS.pg } : {}),
|
|
445
|
-
'@webjsdev/cli': webjsdevRange('cli'),
|
|
446
|
-
'@webjsdev/core': webjsdevRange('core'),
|
|
447
|
-
'@webjsdev/server': webjsdevRange('server'),
|
|
354
|
+
'drizzle-orm': '^1.0.0-rc.3',
|
|
355
|
+
...(dialect === 'postgres' ? { pg: '^8.13.0' } : {}),
|
|
356
|
+
'@webjsdev/cli': 'latest',
|
|
357
|
+
'@webjsdev/core': 'latest',
|
|
358
|
+
'@webjsdev/server': 'latest',
|
|
448
359
|
},
|
|
449
360
|
devDependencies: {
|
|
450
|
-
|
|
451
|
-
// cannot resolve as a caret-prerelease range, so it stays exact (#700).
|
|
452
|
-
'drizzle-kit': SCAFFOLD_DEP_VERSIONS['drizzle-kit'],
|
|
361
|
+
'drizzle-kit': '^1.0.0-rc.3',
|
|
453
362
|
...(dialect === 'postgres' ? { '@types/pg': '^8.11.0' } : {}),
|
|
454
363
|
// The TypeScript compiler, for `npm run typecheck` (webjs typecheck runs
|
|
455
364
|
// tsc --noEmit). Not needed at runtime (Node strips types in place), only
|
|
@@ -487,28 +396,10 @@ export async function scaffoldApp(name, cwd, opts = {}) {
|
|
|
487
396
|
webjs: {
|
|
488
397
|
// Drizzle has no codegen, so there is no dev `before` step. Production
|
|
489
398
|
// applies pending migrations at boot via `webjs db migrate` (drizzle-kit).
|
|
490
|
-
|
|
491
|
-
// the boot-time migrate needs no `webjs` bin in node_modules (#675).
|
|
492
|
-
start: { before: [isBun ? `${bunBoot} db migrate` : 'webjs db migrate'] },
|
|
399
|
+
start: { before: ['webjs db migrate'] },
|
|
493
400
|
},
|
|
494
401
|
}, null, 2) + '\n');
|
|
495
402
|
|
|
496
|
-
// The zero-install Bun entry (#675). `bun run dev` / `start` invoke this via
|
|
497
|
-
// `bun --bun` (see the scripts above). Importing the webjs CLI by bare
|
|
498
|
-
// specifier lets Bun auto-install resolve `@webjsdev/*` and your deps on
|
|
499
|
-
// demand, so a fresh app serves with NO `bun install`. The CLI reads its
|
|
500
|
-
// command (dev / start / db ...) and flags straight from argv. Node apps do
|
|
501
|
-
// not get this file; they run the `webjs` bin directly.
|
|
502
|
-
if (isBun) {
|
|
503
|
-
await writeFile(join(appDir, 'webjs-bun.mjs'),
|
|
504
|
-
'// Zero-install Bun entry (webjs #675). Run via `bun --bun webjs-bun.mjs <cmd>`\n' +
|
|
505
|
-
'// (the dev / start / db npm scripts do this). Importing the CLI by bare\n' +
|
|
506
|
-
'// specifier lets Bun auto-install resolve @webjsdev/* and your deps on\n' +
|
|
507
|
-
'// demand, so the app serves with no `bun install` (install stays optional,\n' +
|
|
508
|
-
'// for editor types and offline runs). Args pass through to the CLI.\n' +
|
|
509
|
-
"await import('@webjsdev/cli/bin/webjs.js');\n");
|
|
510
|
-
}
|
|
511
|
-
|
|
512
403
|
await writeFile(join(appDir, 'tsconfig.json'), JSON.stringify({
|
|
513
404
|
compilerOptions: {
|
|
514
405
|
target: 'ES2022',
|
|
@@ -1490,13 +1381,6 @@ For AI agents, read this before editing scaffolded files:
|
|
|
1490
1381
|
if (!installed) {
|
|
1491
1382
|
console.log(`\n[warn] ${pm} install failed. Run '${pm} install' manually in ${name}/ to finish setup.\n`);
|
|
1492
1383
|
}
|
|
1493
|
-
} else if (isBun) {
|
|
1494
|
-
// Bun zero-install (#675): no install needed; `bun run dev` resolves deps on
|
|
1495
|
-
// the fly. Since #698 they resolve to their package.json versions (a caret
|
|
1496
|
-
// range to its highest match), so point at `bun install` for a frozen
|
|
1497
|
-
// lockfile and editor type intelligence, not a correctness fix.
|
|
1498
|
-
console.log(`Skipped install. Bun resolves dependencies on the fly, so 'bun run dev' and 'bun run start' work as-is (no node_modules).`);
|
|
1499
|
-
console.log(`These resolve to the versions in package.json. Run 'bun install' in ${name}/ to freeze a lockfile and get editor type intelligence.\n`);
|
|
1500
1384
|
}
|
|
1501
1385
|
|
|
1502
1386
|
// Next-steps banner prints LAST so the actionable command is the
|
|
@@ -1508,10 +1392,7 @@ For AI agents, read this before editing scaffolded files:
|
|
|
1508
1392
|
// generate + migrate before the first run (the example User model wants
|
|
1509
1393
|
// its table to exist). Drizzle splits Prisma's `migrate dev` into
|
|
1510
1394
|
// `db:generate` (schema to SQL) then `db:migrate` (apply).
|
|
1511
|
-
|
|
1512
|
-
// zero-install (#682): `bun run dev` resolves deps on the fly, so it works
|
|
1513
|
-
// without an install. Otherwise (Node, or an install that did not run) keep it.
|
|
1514
|
-
const installSegment = (installed || (isBun && !shouldInstall)) ? '' : `${pm} install && `;
|
|
1395
|
+
const installSegment = installed ? '' : `${pm} install && `;
|
|
1515
1396
|
const dbSegment = isSaas ? `${pm} run db:generate && ${pm} run db:migrate && ` : '';
|
|
1516
1397
|
const runCommand = `cd ${name} && ${installSegment}${dbSegment}${pm} run dev`;
|
|
1517
1398
|
// Use `npx webjsdev ui ...` here, not `npx webjs ui ...`. The bare
|
package/lib/runtime-rewrite.js
CHANGED
|
@@ -58,10 +58,14 @@ export function bunifyProse(s) {
|
|
|
58
58
|
'Dockerfile pins `node:24-alpine` (the same Node major CI uses), installs\ndeps (no build step, since Drizzle has no codegen), and starts via',
|
|
59
59
|
'Dockerfile is a pure `oven/bun:1` image (no Node, since `webjs db migrate`\nresolves drizzle-kit and runs under Bun with no `npx`, #570), installs deps\nwith `bun install` (no build step, since Drizzle has no codegen), and starts via',
|
|
60
60
|
)
|
|
61
|
-
// The "Running on Bun" section
|
|
62
|
-
//
|
|
63
|
-
//
|
|
61
|
+
// The "Running on Bun" section frames Bun as opt-in ("force it with --bun").
|
|
62
|
+
// In a bun-flavored app the dev/start scripts ALREADY embed --bun, so reframe
|
|
63
|
+
// it as the configured default.
|
|
64
64
|
.replaceAll('### Running on Bun instead of Node', '### Runtime: this app runs on Bun')
|
|
65
|
+
.replaceAll(
|
|
66
|
+
'The same `package.json` scripts work on\neither; to run under Bun, force it with `--bun` so the server executes on Bun\nrather than the `webjs` bin\'s Node shebang:',
|
|
67
|
+
'This app is configured for Bun. Its `dev` / `start` scripts already force\n`--bun` (which overrides the `webjs` bin\'s Node shebang), so a plain `bun run dev`\nserves on Bun. The other scripts (test / db / check) run on Node, the runtime\nthe `webjs` tooling targets:',
|
|
68
|
+
)
|
|
65
69
|
// Invocation styles first, so "npm create webjs@latest" does not get
|
|
66
70
|
// mangled by the generic "npm <x>" rules below.
|
|
67
71
|
.replaceAll('npm create webjs@latest', 'bun create webjs')
|
package/package.json
CHANGED
package/templates/AGENTS.md
CHANGED
|
@@ -404,29 +404,15 @@ an npm `prestart` hook.
|
|
|
404
404
|
|
|
405
405
|
### Running on Bun instead of Node
|
|
406
406
|
|
|
407
|
-
webjs runs on **Node 24+ or Bun**.
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
bootstrap imports the CLI by bare specifier, so Bun auto-install resolves deps on
|
|
411
|
-
demand and **no `bun install` is needed**:
|
|
407
|
+
webjs runs on **Node 24+ or Bun**. The same `package.json` scripts work on
|
|
408
|
+
either; to run under Bun, force it with `--bun` so the server executes on Bun
|
|
409
|
+
rather than the `webjs` bin's Node shebang:
|
|
412
410
|
|
|
413
411
|
```sh
|
|
414
|
-
bun
|
|
412
|
+
bun install
|
|
413
|
+
bun --bun run dev # or: bun --bun run start
|
|
415
414
|
```
|
|
416
415
|
|
|
417
|
-
`bun create` does not run an install on Bun, so a fresh app serves immediately.
|
|
418
|
-
Under zero-install, Bun's runtime auto-install resolves a BARE import to LATEST
|
|
419
|
-
(it ignores `package.json` and `bun.lock`), so webjs rewrites each declared dep's
|
|
420
|
-
specifier to an inline-versioned one via an `onLoad` transform. The version is the
|
|
421
|
-
`bun.lock` exact when present, else the `package.json` value when it is an
|
|
422
|
-
inline-safe semver (an exact pin, or a caret / tilde / comparator range, which
|
|
423
|
-
Bun resolves to the highest match). A protocol range (`workspace:`, `file:`), a
|
|
424
|
-
wildcard (`*`), and a dist-tag (`latest`) stay at latest. Run `bun install` when
|
|
425
|
-
you want versions frozen identically across machines (it materializes
|
|
426
|
-
`node_modules` from the lockfile) or editor type intelligence. (To run a
|
|
427
|
-
Node-flavored app on Bun instead, force `bun --bun run dev`, which still expects
|
|
428
|
-
an install.)
|
|
429
|
-
|
|
430
416
|
On Node the `.ts` type-stripping is the built-in `module.stripTypeScriptTypes`;
|
|
431
417
|
on Bun (which has no built-in) it comes from `amaro` automatically, so the same
|
|
432
418
|
source serves identically. SSR action-result seeding (an internal hydration
|