Add create-mini-lynx and the preview engine it boots on - #41
Merged
Conversation
One command to a running app: `bun create @amritk/mini-lynx my-app` writes a complete project, installs it, and leaves you one `bun run dev` from the app on screen in a device frame with a size picker. Two packages, because the second one is what makes the first honest: - `@amritk/mini-lynx-preview` — Lynx's Element PAPI over the DOM. It was `apps/playground-mini-lynx/src/lib/`, which a scaffolded app cannot import, and a second copy of a shim this exact is a second thing to be wrong. The playground now boots on the package, so the engine under eighteen screens and the engine under a five-minute-old starter are one implementation. Every import of the runtime in it is `import type`: a preview that called `setEngine` itself would call it on whichever copy of the runtime it resolved, and the symptom of getting that wrong is a blank screen with no error in it. - `@amritk/create-mini-lynx` — the scaffolder. `scaffold.ts` is the filesystem half and prints nothing; `cli.ts` owns the terminal. No dependencies, because an install of its own would be the slowest step in the experience it exists to make fast. The template is a real app rather than a fixture: it installs, type-checks and builds, and the only edit on the way out is the package name. What it deliberately does not do is build a Lynx bundle. A physical device needs a host application and a template-format bundler, neither of which ships here, so the claim is a device-framed preview and the generated README says so in those words — along with the four things a browser cannot show you about a device, and the two-line `src/device.ts` a device build would use. Verified end to end: the scaffolded app installs, type-checks, builds, and runs in Chromium — counter, keyed list and device switcher all live, console clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FzzF3oXCYsdMbmpSjMcRwU
`@amritk/mini-lynx-rsbuild-plugin` and `apps/starter-mini-lynx` landed on main while this branch was adding the browser preview and the scaffolder around it. The two answer different halves of the same question, so the merge is more than textual: the template now carries both loops over one `src/app.tsx`. - `bun run dev` — the device-framed browser preview, on `@amritk/mini-lynx-preview`. Fast edit cycle, no phone. - `bun run dev:device` — `rspeedy dev` through `pluginMiniLynx`: a real `.lynx.bundle` and the QR codes Lynx Explorer scans. What differs between the targets is the entry and nothing else — `src/preview/main.ts` builds an engine because a browser is not one, `src/main-thread.ts` is `renderPage(App)` because a device already has one, and `src/background.ts` is the chunk `NativeModules` lives in. The DOM libs now stop at `src/preview/`, in a second tsconfig pass rather than a comment, so a `document` in app code fails the type check instead of the device. Everything the old template said about not building a Lynx bundle is gone, because it is no longer true. What replaces it is a pointer to docs/mini-lynx-explorer.md, which is honest about which links in the device loop are verified and which are not. Conflicts resolved by keeping both sides: the PUBLISHED list, the package tables in README/AGENTS/architecture, and the rule about what stands in for a playground screen — a build-time package has the starter app, a preview package has the playground it boots, a scaffolder has its template test. Verified from a scaffolded app: both tsconfig passes clean, `vite build` and `rspeedy build` both produce artifacts (26 kB main.lynx.bundle, no encoder warnings — `text-transform` was dropped from the template's CSS because the encoder rejects it), `rspeedy dev` serves a 162 kB encoded template over HTTP, and the browser preview still renders and takes taps with a clean console. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FzzF3oXCYsdMbmpSjMcRwU
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
One command to a running app:
bun create @amritk/mini-lynx my-appwrites acomplete project, installs it, and leaves you one
bun run devfrom the app onscreen in a device frame with a size picker.
Two packages, because the second one is what makes the first honest:
@amritk/mini-lynx-preview— Lynx's Element PAPI over the DOM. It wasapps/playground-mini-lynx/src/lib/, which a scaffolded app cannot import, anda second copy of a shim this exact is a second thing to be wrong. The
playground now boots on the package, so the engine under eighteen screens and
the engine under a five-minute-old starter are one implementation. Every
import of the runtime in it is
import type: a preview that calledsetEngineitself would call it on whichever copy of the runtime it resolved,and the symptom of getting that wrong is a blank screen with no error in it.
@amritk/create-mini-lynx— the scaffolder.scaffold.tsis the filesystemhalf and prints nothing;
cli.tsowns the terminal. No dependencies, becausean install of its own would be the slowest step in the experience it exists to
make fast. The template is a real app rather than a fixture: it installs,
type-checks and builds, and the only edit on the way out is the package name.
What it deliberately does not do is build a Lynx bundle. A physical device needs
a host application and a template-format bundler, neither of which ships here,
so the claim is a device-framed preview and the generated README says so in
those words — along with the four things a browser cannot show you about a
device, and the two-line
src/device.tsa device build would use.Verified end to end: the scaffolded app installs, type-checks, builds, and runs
in Chromium — counter, keyed list and device switcher all live, console clean.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01FzzF3oXCYsdMbmpSjMcRwU
📦 Bundle-size delta vs main (
c03d563→1d808a5)Gzipped bytes of each bundled entry (esbuild, minified, browser/es2022, optional peer deps external). Bundling is deterministic, so unlike a timed benchmark these numbers carry no noise and every Δ is exact. ⚪ within ±0.5% · 🟢 smaller · 🔴 larger. Each package's
core (.)must stay flat as subpath features land — that is the whole charter, andsrc/core-size-budget.test.tsholds the absolute ceiling.