vercel-labs / vercel-labs/native
TypeScript cores have no way to exchange messages with a WebView
Nobody has claimed this yet.
- Dominant language
- Zig
- Stars
- 7.7k
- Forks
- 314
- Avg merge
- 5h
- Merged PRs (30d)
- 13
Description
Environment
- native-sdk v0.10.1
- macOS aarch64 (not platform-specific)
- Zig 0.16.0
What happens
A TypeScript-core app can show a WebView, but the core and the page cannot talk to each other.
- The page cannot call the app. The generated wiring for a TypeScript core registers no bridge dispatcher, so
window.zero.invoke(...)from the page fails withunknown_command(src/bridge/root.zig:156in the v0.10.1 sources). - The app cannot call the page. A TypeScript core has no command to navigate a declared WebView (#290) and no way to evaluate JavaScript or push data into one. Model-driven
web_panesexist only on the ZigUiApp.Options. - The app cannot add the missing piece itself. The build rejects a tree that keeps
src/core.tsalongside a smallsrc/main.zigfor the bridge: "An app has exactly one core" (src/tooling/ts_core.zig:64).
What I expected
A TypeScript-core app with a declared WebView should be able to:
- Answer
window.zero.invoke(...)calls from the page, gated by the existingbridge.commandspolicy in the manifest. - Push a payload into the page from
update(aCmdthat delivers a string/bytes message to a declared WebView by label), so the core can send data without a full page reload.
What we did instead (workaround)
I rewrote my app's core in Zig. My app is a journal: the window is a React page with a TipTap editor, and the native side owns a SQLite database. Loading and saving an entry needs two-way messaging between the page and the database, so src/core.ts became src/main.zig and all app logic moved to Zig. The app works, but every future change to app logic is now Zig work, and we keep the command list in app.json in sync with the handler table in src/main.zig by hand.
Why this matters
Embedding a WebView editor (TipTap, CodeMirror, any ProseMirror-based tool) is a common reason to embed a WebView at all. Today that choice forces the whole app off TypeScript and onto Zig, because the one-core rule forbids a mixed tree. #103 covers the missing bridge for scene-declared shell views on the Zig UiApp path, and #290 covers navigation for TypeScript cores; this issue asks for the full two-way channel between a TypeScript core and its declared WebView.
Suggested direction
- When the manifest declares
bridge.commands, have the generated TypeScript-core wiring register a bridge dispatcher, and let the app export a handler insrc/core.ts(for exampleonBridgeCommand(request)) that returns a result or aMsg. - Add a
Cmd-returning effect that posts a payload into a declared WebView by label, delivered to the page as awindowevent. #290'sCmd.navigateWebViewis the same shape for URLs.
Happy to test against my app. Its Zig bridge is about 230 lines and shows the exact command set a real app needs (database CRUD, a local HTTP call, and two window-chrome commands).
Related: #103, #226, #290
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the TypeScript-core wiring in src/core.ts and src/tooling/ts_core.zig, then inspect bridge dispatch in src/bridge/root.zig and the related navigation work in #290. Reproduce the current build and WebView invocation failure. Done means declared WebViews can receive gated page commands and messages from update without requiring a Zig core.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript, zig
- Domain
- api, desktop, web-dev
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100