Mysten Incubation
Features

Generated Outputs

Current generated-file behavior.

There is no root factory for generated output. The supervisor collects each member's codegenable capability and emits files during devstack up or devstack apply.

Default root for the primary stack (the one your config declares via stackName):

src/generated/

Secondary stacks (any run with an explicit --stack/$DEVSTACK_STACK override that diverges from the config's stackName) emit to a per-stack directory instead, so two stacks of the same app can run side by side without clobbering each other's package-id and wallet-pair-token literals:

.devstack/stacks/<stack>/generated/

The supervisor records the absolute output dir it chose in that stack's manifest as codegen.generatedDir, so the reader (the Vite alias below) consults the same location the writer chose. pnpm dev (primary stack) and pnpm test:e2e (an e2e stack) therefore coexist with distinct generated trees.

Common outputs:

sui/network.ts
accounts/<name>.ts
coins/<symbol>.ts
package/<mvr-placeholder>.ts
dapp-kit/config.ts
walrus/network.ts
seal/<name>.ts
deepbook/<name>.ts
extras.ts

The primary/secondary rule above is the default. An app can pin an explicit output dir in the stack options; outputDir (and the optional stackSubdir) are then honored verbatim, and per-stack isolation becomes the app's responsibility:

import { defineDevstack, account, sui } from '@mysten-incubation/devstack';

const localnet = sui();
const alice = account('alice');

export default defineDevstack({
	members: [localnet, alice],
	codegen: {
		outputDir: 'src/generated',
		stackSubdir: null,
	},
	extras: {
		featureFlag: 'local-demo',
	},
});

Importing generated code

Generated files are normal source imports, resolved through a configurable @generated alias. Runtime state under .devstack/ is not importable app code.

import { suiNetwork } from '@generated/sui/network.js';
import { dappKitConfig } from '@generated/dapp-kit/config.js';

The alias is wired by devstackVitePlugin(), which points @generated at whichever stack is active. It reads the active stack's manifest-recorded codegen.generatedDir (falling back to src/generated/ before the first up), so an import resolves to the primary stack under pnpm dev and to .devstack/stacks/<stack>/generated/ under a secondary stack — automatically, with no import changes.

vite.config.ts
import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';
import { devstackVitePlugin } from '@mysten-incubation/devstack/vite';

export default defineConfig({ plugins: [react(), devstackVitePlugin()] });

The alias prefix is coordinated in three places, all using the same string (default @generated, customizable via devstackVitePlugin({ alias: '@gen' })):

  1. devstackVitePlugin() in vite.config.ts (and vitest.config.ts — Vitest runs its own Vite pipeline; see Vitest).
  2. A tsconfig paths entry so the type checker resolves it:
    tsconfig.json
    { "compilerOptions": { "paths": { "@generated/*": ["./src/generated/*"] } } }
  3. The import specifiers themselves: @generated/....

To force a re-emit, run apply:

devstack apply

When a matching devstack up supervisor is live, apply asks it to emit from the current runtime state. Otherwise, apply boots the stack once, emits, and exits.

On this page