New Native API Improves Embedded JavaScript Access to AI Agents, TypeScript, ESLint, and Beyond

November 6, 2025 | Peter Hoddie, Principal

Native Support

Part of what makes JavaScript developers so productive is the vast ecosystem of tools that has grown around the language. There are tools to check your code for correctness like TypeScript and ESLint, LLM-based AI Agents to answer your coding questions and help write code, and intelligent code editors that provide predictive text entry and immediate syntax checking. Embedded JavaScript developers working with the Moddable SDK use all of these. But there have been limits. Read on to learn how Moddable is growing access to the JavaScript ecosystem for Embedded JavaScript developers.

One way that our XS JavaScript engine makes working with platform-native C code easier is through a JavaScript syntax extension that binds JavaScript functions and classes to C code. Because the feature is unique to XS, we deliberately designed it to be incompatible with standard JavaScript. Unfortunately, this gets in the way of using this powerful feature with LLM-based AI agents, TypeScript, ESLint, and other tools. And because our syntax extension uses @ it also conflicts with the decorators proposal.

New Native Syntax

To let developers enjoy the benefits of these tools across their entire project, we've created a new way to bind platform-native C code to JavaScript that LLMs, TypeScript, and ESLint can understand. Instead of a syntax extension, we use two new global functions, native() and Native(). We call this the "Native API".

  • native() – accepts a string literal with the name of the C function implementing a JavaScript method and returns a callable JavaScript function
  • Native() – accepts a string literal with the name of a C function implementing a destructor and returns a JavaScript class

Here's an example of defining a class using these new global functions.

class Point extends Native("xs_point_destructor") {
    constructor(...args) {
        super();
        native("xs_point").call(this, ...args);
    }
    get x() { return native("xs_point_get_x").call(this); }
    set x(it) { native("xs_point_set_x").call(this, it); }

    get y() { return native("xs_point_get_y").call(this); }
    set y(it) { native("xs_point_set_y").call(this, it); }

    distance(x, y) {
        return native("xs_point_distance").call(this, x, y);
    }
}
export default Point;

For efficiency, the XS compiler optimizes common code patterns using native() and Native(). This eliminates the unnecessary runtime overhead implied by the syntax.

LLM-based AI Agents

By using standard JavaScript syntax, LLMs can more easily train on Embedded JavaScript source code. That lets them better answer your questions and help you code.

To evaluate how clear our new Native API is to JavaScript developers, we asked ChatGPT to explain the Rectangle example from our documentation. Its complete explanation is pretty much on-target, despite being queried prior to this release of the feature in our GitHub repository. As usual for an LLM, some details are wrong (there is no need to register the C callbacks!), but the big picture is accurate. ChatGPT's summary is characteristically flattering for an LLM, and reasonably accurate.

🧩 Why Use This Pattern

It’s the canonical Moddable way to bind JS classes to native implementations β€” lightweight and memory-safe, unlike Node-style FFI or N-API.

It gives you:

  • Native performance for heavy operations
  • Full GC integration
  • JS-friendly syntax

Moddable SDK Updates

We're migrating the Moddable SDK code to use the new Native API. Our focus is widely used APIs, with an emphasis on APIs implementing standard ECMA-419 APIs.

We also ran eslint on many of our modules and examples, correcting a pile of annoying little mistakes along the way.

We encourage you to begin migrating your code too. The conversion is straightforward and has been trouble-free. Moddable has no immediate plans to remove support for our @ syntax, but it is possible in the future.

TypeScript and ESLint

We've updated our TypeScript type declarations to support the new Native API so TypeScript just works. We've taken the opportunity to review, update, and improve many of our TypeScript typings too.

We've also added an ESLint configuration to the root of the Moddable SDK. This has our recommended settings for Embedded JavaScript development. If you are working in the Moddable SDK repository, here's how to quickly lint your code:

cd $MODDABLE/examples/helloworld
eslint

If you are working in your own repository, our ESLint configuration is a great starting point for your own configuration.

Code Editors

Because our new syntax is 100% standard JavaScript, code editors don't show it as an error. This eliminates a lot of red squiggles in Visual Studio Code, Cursor, and other smart code editors. Our updated TypeScript declarations and ESLint configuration are automatically detected by many code editors, giving a more helpful, less distracting, smart-coding experience.

Let's Go!

For many Embedded JavaScript developers working with the Moddable SDK, these improvements require no changes to their code or workflow. They may make your coding experience better by empowering you to use more tools from the JavaScript ecosystem.

Note: To learn more about the Native API syntax, check out our updated XS in C documentation.