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.tsThe primary/secondary rule above is the default. An app can pin an explicit output dir in the stack
options as a back-compat escape hatch — 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.
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' })):
devstackVitePlugin()invite.config.ts(andvitest.config.ts— Vitest runs its own Vite pipeline; see Vitest).- A
tsconfigpathsentry so the type checker resolves it:tsconfig.json { "compilerOptions": { "paths": { "@generated/*": ["./src/generated/*"] } } } - The import specifiers themselves:
@generated/....
To force a re-emit, run apply:
devstack applyWhen 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.