@mysten/sui v2.0 and a new dApp Kit are here! Check out the migration guide
Mysten Labs SDKs

Sui TypeScript Codegen

The @mysten/codegen package automatically generates type-safe TypeScript code from your Move packages, enabling seamless interaction with your smart contracts from TypeScript applications.

This package is currently in development and may have breaking changes.

Features

  • Type-safe Move calls: Generate TypeScript functions with full type safety for calling your Move functions
  • BCS type definitions: Automatic BCS struct definitions for parsing on-chain data
  • Auto-completion: IDE support with intelligent code completion for Move function arguments
  • Package resolution: Support for both MVR-registered packages and local packages

Installation

Install the codegen package as a dev dependency:

npm install -D @mysten/codegen

Quick Start

1. Create a configuration file

Create a sui-codegen.config.ts file in your project root:

import type { SuiCodegenConfig } from '@mysten/codegen';

const config: SuiCodegenConfig = {
	output: './src/contracts',
	packages: [
		{
			package: '@local-pkg/counter',
			path: './move/counter',
		},
	],
};

export default config;

2. Generate TypeScript code

Add a script to your package.json:

{
	"scripts": {
		"codegen": "sui-ts-codegen generate"
	}
}

Then run:

pnpm codegen

This generates TypeScript code in your configured output directory (e.g., ./src/contracts).

Configuration Options

The SuiCodegenConfig type supports the following options:

OptionTypeDefaultDescription
outputstringrequiredThe directory where generated code will be written
packagesPackageConfig[]requiredArray of Move packages to generate code for
prunebooleantrueRemove generated files that are no longer referenced
generateSummariesbooleantrueAutomatically run sui move summary before generating code. Creates a package_summaries directory in your Move package which can be added to .gitignore
privateMethods'none' | 'entry' | 'all''entry'Which private functions to generate: 'none' skips all, 'entry' generates private entry functions, 'all' generates all functions

Package Configuration

Each package in the packages array requires the following options:

OptionTypeRequiredDescription
packagestringyesPackage identifier (e.g., @local-pkg/my-package)
pathstringyesPath to the Move package directory
packageNamestringnoCustom name for generated code
{
  package: '@local-pkg/my-package',
  path: './move/my-package',
  packageName: 'MyPackage'
}

Using Generated Code

Calling Move Functions

The generated code provides type-safe functions for calling Move functions:

import { Transaction } from '@mysten/sui/transactions';
import * as counter from './contracts/counter/counter';

// Increment a counter
const tx = new Transaction();
tx.add(
	counter.increment({
		arguments: {
			counter: '0x123...', // Counter object ID
		},
	}),
);

Parsing BCS Data

Use generated BCS types to parse on-chain object data with the core API:

import { Counter as CounterStruct } from './contracts/counter/counter';

async function readCounter(id: string) {
	const { response } = await client.ledgerService.getObject({
		objectId: id,
		readMask: {
			paths: ['*'],
		},
	});

	if (!response.object?.contents?.value) {
		throw new Error('Expected a move object with contents');
	}

	// Parse with generated BCS type
	const parsed = CounterStruct.parse(response.object.contents.value);
	console.log('Counter value:', parsed.value);
	console.log('Counter owner:', parsed.owner);

	return parsed;
}

Client Configuration

Using with MVR (Move Version Registry)

If your package is registered on MVR, the generated code works without additional configuration.

Local Packages

For local packages using @local-pkg/* identifiers, configure your client with package overrides:

import { SuiGrpcClient } from '@mysten/sui/grpc';

const client = new SuiGrpcClient({
	network: 'testnet',
	baseUrl: 'https://fullnode.testnet.sui.io:443',
	mvr: {
		overrides: {
			packages: {
				'@local-pkg/counter': '0xYOUR_PACKAGE_ID',
			},
		},
	},
});

With dApp Kit

Configure package overrides when creating your dApp Kit instance:

import { createDAppKit } from '@mysten/dapp-kit-core';
import { SuiGrpcClient } from '@mysten/sui/grpc';

const GRPC_URLS = {
	testnet: 'https://fullnode.testnet.sui.io:443',
};

const PACKAGE_IDS = {
	testnet: {
		counter: '0xYOUR_PACKAGE_ID',
	},
};

const dAppKit = createDAppKit({
	networks: ['testnet'],
	createClient: (network) => {
		return new SuiGrpcClient({
			network,
			baseUrl: GRPC_URLS[network],
			mvr: {
				overrides: {
					packages: {
						'@local-pkg/counter': PACKAGE_IDS[network].counter,
					},
				},
			},
		});
	},
});

On this page