IDLize Tool User Guide
This guide is for developers who use IDLize as an ArkUI code generation tool. After reading it, readers should be able to:
- Run the standard generation flow.
- Identify where input declarations, IDL intermediates, and generated code are located.
- Add handwritten IDL or extend an existing interface.
- Verify ArkTS and C++ generated output after changing interface parameters.
For the full IDL language syntax, see IDL_SPEC.md. For command parameters, see CLI_REFERENCE.md.
1. Prerequisites
Prepare the environment from the repository root:
npm i --no-save /path/to/ace_ets2bundle/libarkts.tgz
cd runner
npm run compile
cd ..
npm run download:sdk
Use the libarkts archive produced by ace_ets2bundle; public npm dependencies
continue to use the repository's configured registry.
After these commands complete, you can run the standard generation flow. For full development-environment and release details, see the Developer Guide.
2. Run the Standard Generation Flow
Run this from the repository root:
bash generate.sh
generate.sh invokes runner m3, uses sdk-patched-arkts/ as the prepared SDK,
and passes interfaces/interfaces/arkui-extra/ as extra IDL input. The standard
flow installs all targets:
out/
sig/ # ArkTS / TypeScript peers and component classes
libace/ # C++ modifiers, serializers, and native module glue code
Intermediate artifacts are written under runner/out/:
| Path | Purpose |
|---|---|
runner/out/idl/ |
.idl files converted from .d.ts / .d.ets by etsgen. |
runner/out/peers/sig/ |
Intermediate ArkTS / TypeScript peer output generated by arkgen. |
runner/out/peers/libace/ |
Intermediate C++ output generated by arkgen. |
runner/out/patched-sdk-arkts/ |
Prepared ArkTS SDK declarations. |
runner/out/patched-sdk-ts/ |
Prepared TypeScript SDK declarations. |
runner/out/scraper/ |
IDL input processed by the scraper stage. |
These directories are generated artifacts. Do not edit them manually. To fix an
input, modify handwritten IDL, an SDK patch, or generation configuration, then
rerun bash generate.sh.
3. Check Whether Generated Output Is Correct
When generated code misses a component, method, or attribute, or when a parameter type, optional marker, or return type is wrong, trace backwards through the artifact chain:
- Inspect
out/sig/orout/libace/to confirm whether installed files are missing or wrong. - Inspect
runner/out/peers/sig/orrunner/out/peers/libace/to see what printers emitted. - Inspect
runner/out/idl/to see what IDL the parser received. - If the IDL is already wrong, inspect
runner/out/patched-sdk-arkts/,runner/out/patched-sdk-ts/, and the input patch. - If the IDL is correct but peer output is wrong, inspect
arkgen/generation-config/config.jsonand the related generator.
Useful checks:
rg -n "MyButton" out runner/out/peers runner/out/idl
rg -n "borderWidth" out/sig runner/out/peers/sig
rg -n "setData" out/libace runner/out/peers/libace
4. Add a Handwritten IDL Component
4.1 Write the IDL File
The example below defines a MyButton component:
package arkui.component.mybutton;
import arkui.component.units;
import arkui.component.common;
callback MyButtonClickCallback = void (i32 clickCount);
[Component]
interface MyButton {
constructor();
attribute String label;
attribute ResourceColor backgroundColor;
attribute Length width;
attribute Length height;
attribute boolean enabled;
MyButton onClick(MyButtonClickCallback callback);
MyButton fontSize(Length size);
MyButton borderRadius(Length radius);
};
[ComponentInterface]
interface MyButtonAttribute {
MyButtonAttribute label(String value);
MyButtonAttribute backgroundColor(ResourceColor color);
MyButtonAttribute onClick(MyButtonClickCallback callback);
MyButtonAttribute fontSize(Length size);
MyButtonAttribute borderRadius(Length radius);
MyButtonAttribute enabled(boolean value);
};
Key points:
packagesets the interface namespace.importbrings types from external IDL packages into scope.[Component]marks an ArkUI component interface.[ComponentInterface]marks the attribute setter interface.- Setters usually return the component or attribute interface type to support chaining.
4.2 Place the IDL File
The recommended standard extra-input directory is:
interfaces/interfaces/arkui-extra/mybutton.idl
If you use a custom directory, call runner m3 directly and pass it through the
<idl-files...> positional argument.
4.3 Configure Generation
Whether a component is fully generated is mainly controlled by
arkgen/generation-config/config.json. New components are usually
materialized. To force full generation, add fully qualified names to
forceMaterialized:
{
"forceMaterialized": [
"arkui.component.mybutton.MyButton",
"arkui.component.mybutton.MyButtonAttribute"
]
}
The fully qualified name format is <package>.<InterfaceName>. If a component
is listed in ignoreMaterialized, only a minimal stub is generated.
4.4 Regenerate and Verify
bash generate.sh
find out/sig -name "*MyButton*"
find out/libace -name "*MyButton*"
Common naming conventions:
| Generated artifact | Naming pattern |
|---|---|
| Peer class | Ark<Component>Peer, for example ArkMyButtonPeer. |
| Component class | Ark<Component>Component, for example ArkMyButtonComponent. |
| C++ Modifier | <Component>Modifier, for example MyButtonModifier. |
| Materialized interface implementation | <Name>Internal, for example MyButtonInternal. |
| Native module call | ArkUIGeneratedNativeModule._<method>. |
5. Extend an Existing Component Interface
5.1 Identify the Input Source First
Do not modify runner/out/idl/ or out/. These directories are overwritten on
each generation run.
| Source | Modify this location |
|---|---|
| Handwritten or supplementary IDL | interfaces/interfaces/arkui-extra/ or a custom IDL path passed to runner m3. |
| Upstream ArkTS SDK declaration | sdk-patched-arkts/. |
| Upstream TypeScript SDK declaration | sdk-patched/. |
| Generation configuration | arkgen/generation-config/config.json. |
Use this command to locate handwritten IDL:
rg -n "ExistingComponent" interfaces/interfaces
5.2 Add an Attribute or Method
Add matching declarations to the component interface and the attribute interface:
package arkui.component.existing;
import arkui.component.common;
import arkui.component.units;
[Component]
interface ExistingComponent {
attribute String tooltip;
ExistingComponent shadow(number radius, number offsetX, number offsetY, ResourceColor color);
ExistingComponent animation(optional Duration duration);
};
[ComponentInterface]
interface ExistingComponentAttribute {
ExistingComponentAttribute tooltip(String value);
ExistingComponentAttribute shadow(number radius, number offsetX, number offsetY, ResourceColor color);
};
Regenerate:
bash generate.sh
Generated method names usually match the IDL method names. The first letter is not automatically case-converted.
6. Change Existing Interface Parameters
Common changes:
interface ExistingComponent {
ExistingComponent borderWidth(Length width, optional ResourceColor color);
void setData(sequence<String> data);
ExistingComponent padding(Length value);
ExistingComponent padding(record<String, Length> edges);
};
Compatibility rules:
- Adding an optional parameter is usually backward compatible.
- Adding a new overload is usually backward compatible.
- Changing a parameter type is a breaking change.
- Removing a parameter or method is a breaking change; mark the old API with
[Deprecated]first.
interface ExistingComponent {
[Deprecated]
ExistingComponent oldMethod(String param);
ExistingComponent newMethod(String param, optional i32 flags);
};
Verify both ArkTS and C++ output:
bash generate.sh
rg -n "borderWidth" out/sig runner/out/peers/sig
rg -n "setData" out/libace runner/out/peers/libace
Confirm that:
- ArkTS peer method signatures are updated.
- C++ modifiers accept the new parameter types.
- Serializers encode the new parameter types as expected.
7. Call runner m3 Directly
The standard script is equivalent to:
node runner m3 sdk-patched-arkts ./interfaces/interfaces/arkui-extra/ \
--sdk-stage prepared \
--arkgen-options-file ./arkgen/generation-config/config.json \
--etsgen-options-file ./etsgen/generator-config.json \
--arkgen-interop-types ./runner/interop-types/src/cpp/interop-types.h \
--scraper-options-file ./runner/configs/scraper-config.json \
--arkgen "node arkgen" \
--etsgen "node etsgen" \
--target all \
--no-arkgen-dummy-impl \
--output "./out"
Key parameters:
| Parameter | Purpose |
|---|---|
--sdk-stage prepared |
Start from a prepared SDK. Use idl when only IDL input is used. |
--arkgen-options-file |
ArkUI generation configuration. |
--etsgen-options-file |
.d.ts / .d.ets to IDL conversion configuration; not needed for the idl stage. |
--arkgen-interop-types |
Shared ArkTS/C++ interop types header. |
--scraper-options-file |
Scraper processing-scope configuration. |
--target |
sig, libace, or all. |
--output |
Installed output directory. |
8. IDL Quick Reference
Package and Import
package arkui.component.mycomponent;
import arkui.component.common;
import arkui.component.units.Length as Length;
Interfaces, Attributes, and Methods
interface MyService {
constructor(String name, optional i32 timeout);
attribute String name;
readonly attribute i32 id;
[Optional] attribute String description;
void start();
boolean isRunning();
String getStatus(optional boolean verbose);
static MyService createDefault();
};
If an interface with [Entity=Class] needs to be used as a peer or contains
methods, avoid plain attributes or use the [Accessor=Getter] /
[Accessor=Setter] combination:
[Entity=Class]
interface MyService {
[Accessor=Getter]
attribute String name;
[Accessor=Setter]
attribute String name;
void start();
};
Callbacks
callback OnChangeCallback = void (String newValue, i32 changeId);
interface MyComponent {
attribute OnChangeCallback onChange;
void setOnChange(OnChangeCallback callback);
};
Unions, Sequences, and Records
void setSize((number or String or Length) value);
void setColor(optional (ResourceColor or undefined) color);
void setItems(sequence<String> items);
void setMetadata(record<String, boolean> meta);
Common Extended Attributes
| Extended attribute | Usage | Description |
|---|---|---|
[Component] |
Interface | Marks an ArkUI component. |
[ComponentInterface] |
Interface | Marks a component attribute setter interface. |
[Entity=Class] |
Interface | Generates a class shape with pointer support. |
[Entity=Interface] |
Interface | Generates an interface shape. |
[Optional] |
Attribute | The attribute can be omitted. |
[Deprecated] |
Any declaration | Marks an API as deprecated. |
[Throws] |
Method | The method may throw an exception. |
[Accessor=Getter] / [Accessor=Setter] |
Attribute | Marks an accessor direction. |
[Documentation="..."] |
Any declaration | Inline documentation. |
[DtsName="original"] |
Any declaration | Preserves the original declaration name. |
9. Location Reference
| Content | Location |
|---|---|
| Handwritten IDL | interfaces/interfaces/arkui-extra/. |
| SDK ArkTS patch | sdk-patched-arkts/. |
| SDK TypeScript patch | sdk-patched/. |
| Generation configuration | arkgen/generation-config/config.json. |
| Scraper configuration | runner/configs/scraper-config.json. |
| Etsgen configuration | etsgen/generator-config.json. |
| Output directory constants | runner/src/shared.ts. |