Lynx 4.0: AI-Generated UI, ReactLynx Dynamic Elements, Foldable Device Support, and More Open-Source Elements
← All PostsToday, we are happy to share that Lynx 4.0 is now available!
With this release, we are making it easier to build interfaces with AI, create dynamic elements in ReactLynx, and trace production errors and runtime UI nodes back to source code. Our AI tools help agents understand Lynx APIs and generate interfaces that Lynx can render.
For foldable devices, the host passes size changes to Lynx so pages can adapt to the window using familiar Flex layout and relative units. We are also expanding desktop CSS and Element capabilities, making <webview> and <blur-view> open source, and introducing global memory queries. Let's take a look at what you can build with Lynx 4.0.
Lynx for AI
Give Agents Access to Lynx Documentation
AI coding agents often draw on Web development conventions when writing Lynx. This can lead to properties or layouts that Lynx does not support. To help agents work with the right APIs, we provide the lynx-api-docs Agent Skill: a project-local reference for Lynx APIs, CSS, layout, and Elements that agents can consult before writing code.
These references come from the public @lynx-js/lynx-api-docs package. Install the skill through the community-maintained Lynx Agent Skills repository:
Once installed, agents can access the documentation they need for each task. For example, before building a scrolling list, an agent can check the properties, events, and layout constraints of <scroll-view>. For more project configuration options, see Lynx for AI.
From Model Conversations to Native UI
With Lynx A2UI, agents can go beyond writing code and generate interfaces at runtime. The model produces structured protocol messages, and Lynx turns them into native UI. As new messages arrive, the interface updates progressively.

Agents generate protocol messages from a component catalog. Lynx handles rendering and interaction.
Building on the previously released A2UI renderer, we have added the lynx-a2ui Skill, maintained and distributed through lynx-community/skills:
The skill first reads your application's capability catalog, then generates A2UI messages that follow its component, function, and parameter constraints. You can use the default catalog or provide your own, so generated interfaces use capabilities your application already supports. For a full introduction, see Generative UI on Lynx with A2UI.
Simulated Example
Let's see this in action with a weather query. In the example below, a mock agent sends A2UI protocol messages progressively, and ReactLynx uses components from the catalog to render a weather card. Click the button to switch cities: your interaction is sent back to the mock agent as an Action, and its next messages update the page. This shows how streamed messages and user interactions work together.
Try the Playground
Chat with a model on the Create page of the Lynx A2UI Playground to see interfaces generated and updated in real time. In Examples, edit and replay existing cases to explore how protocol messages correspond to rendered output. In Catalog, combine built-in components and preview the results.
Generate Interactive UI with OpenUI
With the lynx-openui Skill, you can describe an interface in natural language and generate a declarative OpenUI Lang v0.5 program. Pass the result to <OpenUiRenderer> from @lynx-js/genui/openui to render interfaces with streaming generation, reactive state, and tool calls.
The skill guides agents to read the built-in catalog or your application's component signatures first. It then checks component names, positional arguments, and references, helping agents generate programs that match the renderer's capabilities. By default, it produces a complete program. Enable edit mode or mergeStatements explicitly to generate only the changed statements for incremental updates.
For interactive interfaces, use $state to express reactive state, Query() to read host data, and Action() to coordinate interactions. Queries and writes use only tools that the host actually provides. A Mutation() must be triggered by an explicit Action, such as a user clicking a submit button. This lets generated interfaces both display content and participate in the application's existing workflows.
See OpenUI in ReactLynx for integration details, or try the Lynx GenUI OpenUI Playground.
ReactLynx
Dynamically Create and Clone Elements
You can now create and clone Lynx elements dynamically with ReactLynx's createElement and cloneElement. These familiar React APIs give you more flexibility when an element's type is only known at runtime, or when you need to adjust the properties of an existing element:
This makes it easier to build configuration-driven interfaces and reusable components. When you already know the component structure at development time, we still recommend writing JSX directly. This lets the compiler analyze the static structure and optimize rendering. For more on these trade-offs, see Compiler-Informed Rendering.
Unified Debug Metadata
Production errors often point to minified JavaScript, and locations in Main Thread bytecode do not directly correspond to source line and column numbers. To make these issues easier to investigate, our build tools now bring JavaScript and CSS source maps, bytecode debugging information, and UI source maps together in debug-metadata.json.
You can use this metadata in two ways:
- Map production errors to source: restore source file locations from bundled error stacks. Main Thread bytecode locations are first mapped to the encoded JavaScript, then back to the original source.
- Map UI nodes to source: export the runtime UI tree from the client and locate the JSX that created each node to help diagnose interface issues.
UI source maps are disabled by default. Enable them explicitly in pluginReactLynx:
Production builds delete debug-metadata.json after generation by default. To map production errors, preserve and host the debug metadata that corresponds to each build artifact. Mapping UI nodes also requires the runtime to access the corresponding debugMetadataUrl. See Map Errors to Source and UI Source Map for setup details.
Adapting to Foldable Devices
At its September event, Apple unveiled its first foldable iPhone, iPhone Duo. Unfold the screen and the page you were reading gains a fresh canvas; fold it back and the content has to settle into a smaller space. The job of an app is to make the interface flow gracefully between the two.
Lynx already supports foldable devices and is in production use in TikTok. We aim to keep integration simple: the host passes size changes to Lynx by updating screen metrics, viewport, and GlobalProps together, while the frontend continues to use familiar Flex layout and relative units to adapt. The page then adjusts automatically as the window resizes. For integration details, see Adapting to Foldable Devices.

Folding

Unfolding
CSS
Media Queries
Lynx 4.0 implements a subset of CSS Media Queries Level 4, so you can use @media rules to apply different styles based on device and viewport conditions.
You can adapt layouts and styles to viewport dimensions, aspect ratio, orientation, pixel density, and color scheme preferences. Alongside min- and max- syntax, Lynx supports and, or, and not conditions, comma-separated query lists, and Level 4 range syntax such as width >= 768px.
For the full syntax, units, supported features, and limitations, see Media Queries.
Desktop-Only Capabilities (macOS and Windows)
We are continuing to expand desktop CSS support with customizable text carets and multi-layer mask compositing. Both capabilities are currently available in the Clay rendering backend on macOS and Windows. They are not yet available in the native rendering backends on Android, iOS, or HarmonyOS. See each API page's compatibility table for platform details.
Custom Text Carets
Four new Lynx-specific -x-caret-* properties let you customize the text insertion caret in <input> and <textarea>:
-x-caret-gradient: set the caret gradient.-x-caret-width: set the caret width.-x-caret-height: set the caret height.-x-caret-radius: set the caret corner radius.
Multi-Layer Mask Compositing
mask-composite controls how the current mask layer combines with the layers beneath it. It supports add, subtract, intersect, and exclude for adding, subtracting, intersecting, or excluding overlapping regions.
Element Updates
Open-Sourcing <webview>
With Lynx 4.0, <webview> is now open source. You can use it to embed web pages in your Lynx application and reuse existing Web content across Android, iOS, HarmonyOS, macOS, and Windows.
Set an explicit width and height for <webview>. You can load a URL or provide an HTML string directly.
Load Web Content
Use src to specify a URL:
Load an HTML String
Use html to provide HTML content:
For more properties, events, and methods, see the <webview> API reference.
Open-Sourcing <blur-view>
We are also making <blur-view> open source, with support for Android, iOS, and HarmonyOS. You can use it to apply Gaussian blur to the content behind overlays and panels, similar to CSS backdrop-filter: blur.
Basic Usage
On Android, use android-capture-target to identify the background element to blur, and set flatten={false} on that target:
Liquid Glass on iOS
See the <blur-view> API reference for available properties and their platform support.
Other Updates
Global Lynx Memory Queries
When your application hosts multiple Lynx pages, you may need to know which instances are still alive and where their memory is being used. With global Lynx memory queries on iOS and Android, you can asynchronously collect memory usage attributed to live Lynx instances in the current process. The results are grouped into categories such as Elements, UI/Views, Main Thread runtimes, and Background Thread runtimes.
Use this capability to request a snapshot when investigating memory pressure or other issues. To further trace references between JavaScript objects, use the query results to select an instance, then analyze its heap snapshot.
Get Started with Lynx 4.0
Follow Integrate Lynx 4.0 with an Existing App to update your Lynx and PrimJS dependencies to 4.0.x, along with the supporting dependencies for your target platform. For the complete list of engine updates and fixes, see the Lynx 4.0 release notes.
Thank you to everyone who reports issues, contributes code, and shares their experience with the Lynx community. Let's build more native experiences together with Lynx 4.0!


