Elk — a Mastodon Client
To prove Vue Lynx can carry a real product-grade app, we ported
Elk — the beloved Mastodon web client
by Anthony Fu and team — into a native Mastodon client. It browses any
public Mastodon instance as a guest (default mas.to), with timelines,
threads, profiles, search, trends, dark mode and more.
Try it below: the Web tab runs the real app on Lynx for Web against a
live Mastodon instance; switch to the QR Code tab and scan it with
Lynx Go / Lynx Explorer (see Quick Start for
installing it) to run the same main.lynx.bundle natively on your phone.
Why Elk is a serious test
Elk is a Nuxt 3 app with ~196 components, 55 pages and 50 composables. Vue Lynx has no Nuxt (no SSR, file routing, Nitro, auto-imports) and no DOM — so instead of forking, the port reuses Elk's framework-agnostic layers and rebuilds the UI on Lynx elements:
The full feature-parity checklist (including what's deliberately not ported and why — OAuth redirects, TipTap, PWA, Shiki, blurhash…) lives in PRD.md, the architecture map in PORTING.md, and side-by-side screenshot comparisons against the original elk.zone in screenshots/.
Highlights
- The content renderer is the crown jewel: Mastodon statuses arrive as
sanitized HTML. Elk parses them into an AST and renders vnodes; the port
keeps the parse step byte-for-byte and only swaps the vnode targets —
custom emoji become inline
<image>, mentions/hashtags become tappable<text>runs that push vue-router routes. - Native virtualized timeline: the infinite timeline is a Lynx
<list>withestimated-main-axis-size-pxhints; masto.jsPaginatoriteration and Elk's reorder/buffer logic drive it unchanged. - Deep links: pass
globalProps: { initialPath: '/mas.to/tags/caturday' }to the LynxView and the app opens on that route — the same mechanism a host app would use for notification taps. - Guest + token sessions: browse anonymously like Elk's guest mode, or paste a personal access token in Settings to unlock home timeline, notifications, posting, boosts and favourites.