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:

  1. Inspect out/sig/ or out/libace/ to confirm whether installed files are missing or wrong.
  2. Inspect runner/out/peers/sig/ or runner/out/peers/libace/ to see what printers emitted.
  3. Inspect runner/out/idl/ to see what IDL the parser received.
  4. If the IDL is already wrong, inspect runner/out/patched-sdk-arkts/, runner/out/patched-sdk-ts/, and the input patch.
  5. If the IDL is correct but peer output is wrong, inspect arkgen/generation-config/config.json and 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:

  • package sets the interface namespace.
  • import brings 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.