clone

a deno framework for local-first web apps that open instantly, work offline and sync when users choose

main
lofi / docs / spikes / astro-deno / evidence / 2026-07-15.md
2026-07-15.md 4.4K rendered
1# Astro + Deno toolchain evidence — 2026-07-1523Issue: [#6](https://github.com/FelineStateMachine/lofi/issues/6)\4Baseline commit: `0843833`\5Machine: macOS 26.5.1, Deno 2.9.0, Headless Chrome 150.0.0.0\6Pins: Astro 7.0.9, @astrojs/preact 6.0.1, Preact 10.29.7, Jazz 2.0.0-alpha.5378## Go decision910Graduate Astro static output with Deno as the only public command runtime. Do not install the Deno11Astro adapter until an on-demand route actually exists. The PWA target benefits from a prerendered12shell; a server adapter adds runtime modules and deployment choices without serving M1.1314## Exact command surface1516```sh17deno task dev18deno task check19deno task test20deno task build21deno task preview22```2324The build produced one prerendered route, wrote a short Git build identity, and ran the nested-dist25secret scan. The Deno preview served the retained production output and printed its URL plus build26identity. No Node command or global Node installation was used.2728Routine `check` and `build` disable Jazz's managed development server, so neither command publishes29a schema or exposes server secrets to Astro. Development retains automatic schema publication. The30production bundle contains no `__LOFI_PROTOTYPE__` test probe, and preview serves the web manifest31as `application/manifest+json`.3233## Two-island and lifecycle result3435Two independent `client:load` Preact roots share one browser-global Jazz database and one query36subscription. A write in either root updates both. Reload and explicit client recreation retained37OPFS data. Five HMR edits preserved local identity/data and settled after each edit at:3839```text40active clients: 141active component consumers: 242active vendor subscriptions: 143active mutation listeners: 144```4546Two concurrent recreation requests coalesced to one replacement client and returned to the same 1 /472 / 1 / 1 steady state. Lifecycle tests also defer database initialization past HMR disposal and48verify that the obsolete module never attaches its store or mutation listener.4950The runtime forwards SIGINT/SIGTERM to Astro so the wrapper does not orphan a development server.51Astro 7's agent-detected background mode is disabled inside the stable lofi wrapper; the public52command remains foreground and Ctrl-C behaves conventionally.5354## Startup measurements5556Measurement begins at command invocation and ends when Astro prints the usable local URL.5758| Mode | Samples | Median | Slowest |59| ----------------------------------- | ---------------------------------------- | -------: | -------: |60| Cold app caches cleared + `--force` | 1 | 1,187 ms | 1,187 ms |61| Warm | 1,210 / 1,179 / 1,181 / 1,178 / 1,180 ms | 1,180 ms | 1,210 ms |6263Astro's internal warm measurements were 886 / 853 / 839 / 828 / 851 ms. The lofi wall time is the64contract value because it includes the wrapper. Dependency download was already warm and is not65misreported as an uncached project-creation measurement; that belongs to M2's generator.6667The final checkout-to-retained-write run took 18,998 ms from `deno task dev` invocation through a68local durability-confirmed write visible in both islands. Reload retained the row and restored the 169/ 2 / 1 / 1 steady state. This validates DX-PROTOTYPE-01's 60-second cached-checkout budget.7071## npm-compatibility findings7273The exact stack passed after retaining these settings:7475- `nodeModulesDir: "auto"`;76- explicit Preact subpath imports, including `jsx-dev-runtime`;77- `vite.resolve.noExternal: ["@astrojs/preact"]` to resolve Astro's virtual Preact options module;78- a Preact-aware app `tsconfig.json`;79- workspace filesystem allowance for Jazz's Deno npm-cache WASM path;80- a preseeded internal Jazz app ID to avoid the plugin's first-run `.env` restart race.8182Astro's dependency graph resolves Vite 8.1.4 while the standalone Jazz control remains pinned to83Vite 8.0.1. Both passed. Investigation stayed inside Deno; the agreed Node-build fallback was not84needed.8586A clean-room server control also built and ran with `@deno/astro-adapter@0.6.0` when hostname, port,87and start were explicit. Static mode is still the M1 choice because no request-time rendering88requirement exists.8990## Contract delta9192No public Node fallback is necessary. DX-START-01, DX-BUILD-01, and the M1 part of DX-CMD-01 are93validated. DX-HMR-01 uses one underlying subscription per shared query rather than duplicating one94per island consumer.