How to Use the Generated TypeScript Code with a Frontend Framework

Install the @typescript/native-preview package to import factory functions and AST types from the microsoft/typescript-go repository, then use the Emitter API to print constructed syntax trees into source strings that any frontend framework can consume.

The microsoft/typescript-go repository provides a code generator that produces TypeScript AST definitions and factory helpers from the ast.json schema. Because these artifacts ship as the public npm package @typescript/native-preview, you can use the generated TypeScript code with a frontend framework just like any other dependency, enabling dynamic code generation that remains fully typed and validator-compliant.

What the Generator Produces

The code generator located at _scripts/generate-ts-ast.ts reads the ast.json schema and outputs plain TypeScript files to /_packages/native-preview/src/ast/. The generated codebase consists of three primary modules:

  • ast.generated.ts – Contains complete TypeScript AST type definitions, including interfaces for every node type, SyntaxKind enums, and utility types.
  • factory.generated.ts – Exports factory helpers such as createVariableStatement, createFunctionDeclaration, and createIdentifier for programmatically constructing AST nodes.
  • is.generated.ts – Provides type-guards and predicates like isIdentifier and isFunctionDeclaration for runtime node validation.

Because the output is standard TypeScript, you import these modules directly into frontend projects without special loaders or native bindings.

Installation and Configuration

Add the library to your project using your preferred package manager:

npm install @typescript/native-preview

The package uses ES modules with module: "nodenext" and verbatimModuleSyntax. Configure your tsconfig.json to match these requirements:

{
  "compilerOptions": {
    "module": "nodenext",
    "target": "es2022",
    "moduleResolution": "nodenext",
    "esModuleInterop": true,
    "skipLibCheck": true,
    "strict": true
  }
}

This configuration ensures the TypeScript compiler can resolve subpath exports like @typescript/native-preview/ast correctly.

Creating and Emitting AST Nodes

Import the generated symbols from the ast subpath to access both the type definitions and factory functions:

import {
  createVariableStatement,
  createVariableDeclarationList,
  createVariableDeclaration,
  createIdentifier,
  SyntaxKind,
} from "@typescript/native-preview/ast";
import { projectFromFiles } from "@typescript/native-preview";

Construct AST nodes using the factory helpers. For example, to build a variable declaration:

const decl = createVariableDeclaration(
  createIdentifier("counter"),
  undefined,
  undefined,
  undefined
);

const stmt = createVariableStatement(
  undefined,
  createVariableDeclarationList([decl], /* flags */ 0)
);

Convert the AST back to source code by creating an in-memory project and invoking the emitter, as demonstrated in /_packages/native-preview/test/sync/api.test.ts:

const project = await projectFromFiles({
  "/src/generated.ts": ""
});

const sourceFile = project.getSourceFile("/src/generated.ts")!;
sourceFile.statements = [stmt];

const printed = project.emitter.printNode(sourceFile);
console.log(printed);
// → "let counter;"

The printNode method returns a standard JavaScript string that you can pass to framework compilers, dynamic eval contexts, or code sandbox runners.

Frontend Integration Example

You can integrate the emitter output directly into a React application to generate components dynamically. The following example constructs a function declaration programmatically and prints it to a string:

import React from "react";
import {
  createFunctionDeclaration,
  createParameterDeclaration,
  createBlock,
  createExpressionStatement,
  createCallExpression,
  createIdentifier,
} from "@typescript/native-preview/ast";
import { projectFromFiles } from "@typescript/native-preview";

async function generateReactComponent() {
  // Build parameters: props
  const param = createParameterDeclaration(
    undefined,
    undefined,
    createIdentifier("props"),
    undefined,
    undefined,
    undefined
  );

  // Build JSX expression: React.createElement("div", undefined, "Hello, " + props.name)
  const jsx = createCallExpression(
    createIdentifier("React.createElement"),
    undefined,
    [
      createIdentifier(`"div"`),
      undefined,
      createIdentifier(`"Hello, " + props.name`),
    ]
  );

  // Build function body and declaration
  const body = createBlock([createExpressionStatement(jsx)], true, true);
  const fn = createFunctionDeclaration(
    undefined,
    undefined,
    undefined,
    createIdentifier("Greeting"),
    [param],
    body,
    undefined,
    SyntaxKind.Unknown
  );

  // Emit to source string
  const project = await projectFromFiles({ "/src/dynamic.tsx": "" });
  const sourceFile = project.getSourceFile("/src/dynamic.tsx")!;
  sourceFile.statements = [fn];
  const source = project.emitter.printNode(sourceFile);

  console.log(source);
  // Output:
  // function Greeting(props) {
  //   return React.createElement("div", undefined, "Hello, " + props.name);
  // }
}

In production builds, feed the emitted string through your standard TypeScript or Babel pipeline (e.g., ts-loader in Webpack) to enable type checking and source maps for the generated code.

Summary

  • The microsoft/typescript-go repository publishes generated AST types and factories to the npm package @typescript/native-preview.
  • Import factory functions from @typescript/native-preview/ast to build AST nodes programmatically without string concatenation.
  • Use projectFromFiles to create an in-memory project, then call project.emitter.printNode() to serialize AST nodes into executable JavaScript or TypeScript source code.
  • The resulting strings integrate with any frontend framework by passing them to dynamic component compilers or build pipelines.

Frequently Asked Questions

What npm package contains the generated TypeScript code?

The package is named @typescript/native-preview. It contains the same files produced by the generator script _scripts/generate-ts-ast.ts, including ast.generated.ts and factory.generated.ts.

Which module resolution strategy is required for @typescript/native-preview?

You must use "module": "nodenext" and "moduleResolution": "nodenext" in your tsconfig.json. The package relies on ES module subpath exports (e.g., @typescript/native-preview/ast) that require Node.js-style resolution.

How do I convert AST nodes back to source code strings?

Create a project using projectFromFiles(), retrieve the source file handle, assign your AST nodes to sourceFile.statements, then call project.emitter.printNode(sourceFile). This pattern is validated extensively in /_packages/native-preview/test/sync/api.test.ts.

Can I use this package with React or Vue for dynamic component generation?

Yes. The factory functions allow you to construct function declarations, JSX elements, and component bodies programmatically. After printing the AST to a string with the emitter, you can feed the output into React's React.createElement or compile it with Babel/TypeScript for use in Vue render functions.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →