How Low-Code Rendering Works: From JSON Schemas to Runtime Engines
This article explains the concept of low-code rendering, the standard protocols that describe component maps, utils, and component trees, and compares code generation versus runtime rendering approaches while outlining current frameworks, pain points, and future architectural plans for Alibaba's low-code engine.
What is low-code rendering?
Low-code rendering converts a JSON‑based schema, which browsers cannot interpret directly, into visual pages using a low-code rendering engine.
Low-code rendering process
Similar to cooking with a recipe and ingredients, low-code rendering follows a formula that includes a standard protocol (the "recipe") and assets (the "ingredients").
Standard protocol
The protocol defines how ProCode components are mapped to low-code JSON, how utilities are described, and how the component tree mirrors JSX.
componentsMap – describes component information and whether destructuring is used.
utils – describes utility functions such as lodash.clone.
componentsTree – describes the component hierarchy similar to JSX.
Asset package protocol
Since browsers cannot import npm packages directly, an asset‑package protocol provides URLs for components and utilities needed at runtime.
Example: a packages entry lists component URLs; after loading, components can be accessed via window.Next.Button.
Rendering methods
Code generation rendering (output‑code rendering)
Runtime rendering
Most Alibaba low‑code platforms use runtime rendering; code generation is reserved for performance‑critical cases.
Code generation rendering
The schema is transformed into Vue, React, or other source code, which is then bundled and executed in the browser. The process relies on existing front‑end build tools.
Runtime rendering
The schema is interpreted directly in the browser, eliminating a pre‑compilation step.
Rendering capabilities
Key capabilities include retrieving source components, parsing props, handling children, preserving context (loops, slots), node updates, loops, and component instances.
Node update mechanisms
Two strategies are used:
Full update – recompute the entire page tree on any data change.
Incremental update – only update nodes that depend on the changed data, typically implemented with MobX observers.
Component rendering details
Props can be static values, JSExpression for computed values, or JSFunction for callbacks. Slots are described with JSSlot to render ReactNode‑type parameters.
Page rendering flow
The engine executes lifecycle methods (React 16 style or equivalent for other stacks), recursively parses the component tree, and generates page context using prototype inheritance to share data between blocks and the page.
function renderNode(node) {
if (!node) return null;
const Component = components[node.componentName];
const props = compute(node.props);
const children = node.children.map(d => renderNode(d));
return React.render(Component, props, children);
}
renderNode(schema);Current runtime frameworks
lowcode‑react‑renderer / lowcode‑rax‑renderer (built on renderer‑core)
Render‑Engine (internal React‑based engine for application‑level rendering)
Rax‑Engine (Rax‑based application‑level engine)
Pain points and solutions
Maintaining three separate runtimes increases cost; the plan is to extract common logic into renderer‑core and adapt differences via plugins. Debugging is difficult for low‑code users; a dedicated debugging capability will be added and demonstrated at an upcoming conference.
Future roadmap
The architecture will place shared runtime logic in Renderer‑Core , with React and Rax renderers built on top, while specialized capabilities (canvas rendering, application rendering) will be provided via extensible plugins. Server‑side rendering and enhanced debugging are also planned.
https://lowcode-engine.cn
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
