How I Built Vue Lynx with AI in Two Weeks
← All PostsVue developers have wanted native for years. The "Vue + Lynx = Vue Native" tweet pulled 1.7k likes. The Vue integration issue on our repo hit 1,600 upvotes — our biggest feature request ever. The demand was clear; the question was bandwidth.
When Lynx open-sourced a year ago, Evan You and Rich Harris both shouted it out, but production-quality framework integration has always demanded serious engineering bandwidth. Then projects like Vercel's web streams rewrite and Cloudflare's ViNext showed how solo engineers, armed with AI, can ship what used to take a team. That changed the math for me.
Vue already has the foundation: a mature Custom Renderer API. I spent a weekend on it. One ~$1,400, 37-hour hackathon. It started with a design exploration: “Can Vue's Custom Renderer even work with dual-thread code splitting, and how?” By 3am Sunday I was debugging “Tap to increment doesn't work” with Claude. By Monday morning, I had a working TodoMVC. I couldn't resist dropping a subtle subtweet, and it immediately took off on X.
Introducing Vue Lynx
The next two weeks of evenings and weekends went into making it real: 160+ commits across ~180 sessions.
I could have shipped after week one. But if you know me, you know my principle:
When things actually work, you let the demos do the talking.
Check vue.lynxjs.org for 20+ example apps running natively and on the web — you can try them without leaving your browser.
We cover the full Composition API, <Transition>, <Suspense>, and ecosystem integrations including Vue Router, Pinia, Tailwind CSS, and TanStack Query. We also ported Lynx's official tutorial (Waterfall Gallery and Swiper) to showcase native components and Main Thread Script for zero-latency gestures. A HackerNews clone brings them all together.
Try It Today
It's open source, of course. If it sparked something, give it a Star! And give some love to the Lynx Engine and Lynx Frontend Stack too. They are the shoulders we're standing on.
I'd love for the Vue and Lynx communities to build on it together. Issues, PRs, and feedback are all welcome.
“Harness” Engineering
You gotta use the hottest word after “AI”, “vibe”, and “agentic” — harness.
No humans were harmed to write code in the making of this project.
Setting Up the Architecture for AI
There were two prior community efforts. The second, from the Vue Vine maintainer @Shenqingchuan, went impressively far, even getting Main Thread Script demos running. But both kept Vue on the main thread just like the Web. This works on Lynx, but it's not taking advantage of the dual-thread architecture Lynx is known for: offload the heavy framework re-rendering on background and ensure the native UI thread stays non-blocking and is only tapped when needed (with Main Thread Scripts).
This was the core architectural decision I validated on Day 1. In Vue Lynx, the entire Vue runtime runs on the Background Thread. A lightweight ShadowElement linked-list tree mirrors the native element tree in memory, and every DOM mutation gets serialized into a flat ops buffer shipped to the Main Thread in one batch per tick:
To keep the agent aligned with this dual-threaded architecture and stop it drifting toward the single-threaded Web model it defaults to, I embedded all critical plans directly in the source tree: design discussion notes, decision logs, and post-implementation learning as cross-session context. Each new session picks up where the last left off, inheriting our architectural constraints and the reasoning that shaped the code.
Bridging the Vue Upstream Tests
The most critical investment in any AI-driven development is feedback. Ideally, to ensure conformance with official Vue, we'd reuse Vue's upstream test suite directly. But Vue's test suite assumes a single-thread DOM. How do you run it to test a dual-thread renderer?
Fortunately, Lynx already has the infrastructure for dual-threaded testing environments. So we can rewire the suite to run through our dual-thread pipeline — BG ShadowElement → ops buffer → syncFlush() → MT applyOps → PAPI → jsdom — then let the agent grind until no remaining failures are fixable (effectively a Ralph Loop).
The result: 852 passed out of 949 upstream tests. Every failure is accounted for in a skiplist with documented reasons, and all turned out to be negligible. See the full report and skip analysis.
We also added our own tests for Lynx-specific surface area such as <list> elements, bindtap events, and Main Thread Scripting APIs. With the pipeline proven, I pushed further and forked the 7GUIs benchmark from the official Vue docs as a stress test.
Agentic E2E Verification Loop
But those classic machinery tests can't catch real UI bugs that used to require human evaluation: a misaligned CSS layout, an interaction broken on a real device. For advanced Vue features like <Transition> and <Suspense>, you need to see them run and interact to verify the behavior.
With the right harnessing, writing examples isn't just demoing — they double as workloads that the agent can evaluate automatically. I wired up two execution environments: iOS Simulator via Lynx DevTool MCP/CLI/Skill, and an agent-controlled browser via Lynx for Web. The loop is simple: run an example in both, observe and verify the output, and let any regression trigger a fix. No human in the loop.
I started with Vue core features, where correctness is well-defined: the agent reads the official docs, writes an example, and checks whether the output conforms. Then I expanded the scope to ecosystem integrations: Vue Router, Pinia, TanStack Query, and Tailwind CSS.
For the final exams, I tried a different approach — one I'd later learn has a name: differential evaluation. I let the agent port existing applications and verify the output against the originals. The first used the canonical Vue HackerNews implementation as ground truth, running both the Web version and the Vue Lynx port with Lynx for Web side-by-side in the browser; the second used existing ReactLynx demos as reference, porting them to Vue Lynx and verifying parity on the iOS Simulator via Lynx DevTool MCP. The harness doesn't need to know what “correct” looks like in the abstract. It just needs the two outputs to agree.
The Bill
The numbers tell a story. Output tokens — the code and text Claude actually wrote — account for just 8% of the cost. The other 92% is comprehension: re-reading the codebase, ingesting tool outputs, and re-processing conversation history across 31,700 API turns. That's 2.5 billion tokens of reading to produce 6.8 million tokens of writing — a 370:1 ratio. This is what “agentic” actually looks like at the billing level.
Was the “$6,500” API rate worth it? Claude gifted me the $200 Claude Max through its Open Source program, thankfully.
What's Next?
This project started as one person's nights-and-weekends effort. I'd love to explore with the Vue core team how we can shape the future of Vue on native together. Personally, and on behalf of the Lynx team, we're committed to supporting its growth.
Vue Lynx is pre-alpha. The architecture is solid, but Vue's API surface is large, and we haven't verified every corner of it.
- Features like
KeepAliveandTeleportlikely need runtime adaptations. <style scoped>andv-modelon native inputs are solvable but not yet implemented.- The Main Thread Script API currently reuses ReactLynx's directive-based design. A more Vue-idiomatic approach (like
<script main-thread setup>) is worth exploring. - Vue DevTools integration with the Lynx DevTool app.
And beyond Vue core, there's a massive Vue ecosystem waiting for us to adapt and grow on native.
The vision is simple: Vue developers should be able to ship native apps as naturally as they ship for the web today. We're not there yet, but the foundation is in place, and the path is clear.
If you've read this far: try it. Build something. Tell us what's missing.
Oh, and by the way: Lynx was initially created with Vue 2.
Originally published as an X Article on March 26, 2026.