Type definitions and schema parser for Stately
npm install @statelyjs/schema> Type definitions and schema parsing for Stately applications


This package provides the foundational type system for Stately's frontend. It parses OpenAPI schemas into a typed AST (Abstract Syntax Tree) that powers the UI's form generation, validation, and type safety.
This 'schema' package is a low-level package used internally by Stately. See @statelyjs/stately for the user facing package.
``bash`
pnpm add @statelyjs/schema
> Note: Most users should use @statelyjs/ui which re-exports this package with additional UI integration. Use @statelyjs/schema directly only if building custom tooling or plugins without the UI layer.
OpenAPI schemas are parsed into nodes - typed representations of each schema element:
`typescript
// A string field
{ nodeType: 'string', nullable: false }
// An object with properties
{
nodeType: 'object',
properties: {
name: { nodeType: 'string', nullable: false },
age: { nodeType: 'integer', nullable: true },
},
required: ['name'],
}
// A reference to another entity
{ nodeType: 'link', inner: { nodeType: 'ref', $ref: '#/components/schemas/SourceConfig' } }
`
The Schemas type is the single source of truth for your application's type system. It combines:
1. Config: Your OpenAPI-generated types (components, paths, operations)
2. Plugins: Type augmentations from installed plugins
3. Derived Types: EntityData, StateEntry, and other computed types
`typescript
import type { StatelySchemas, DefineConfig } from '@statelyjs/schema';
import type { components, paths, operations } from './generated/types';
type MySchemas = StatelySchemas
`
Plugins extend the schema with additional node types:
`typescript
import type { DefinePlugin, NodeMap, StatelySchemas } from '@statelyjs/schema';
// Define custom nodes
interface MyNodes extends NodeMap {
myCustomType: { nodeType: 'myCustomType'; value: string };
}
// Create plugin type
export type MyPlugin = DefinePlugin<'my-plugin', MyNodes>;
// Use with Schemas
type AppSchemas = StatelySchemas
`
`typescript
import { createStately } from '@statelyjs/schema';
import { PARSED_SCHEMAS } from './generated/schemas';
import openapiDoc from './openapi.json';
const stately = createStately
// Access schema utilities
const entityNode = stately.utils.getNode('Pipeline');
const isValid = stately.utils.validate(data, 'Pipeline');
`
When using @statelyjs/codegen with entry points, some schemas are split into a separate runtime bundle for lazy loading. Configure the loader to enable this:
`typescript
import { createStately } from '@statelyjs/schema';
import { PARSED_SCHEMAS } from './generated/schemas';
import openapiDoc from './openapi.json';
const stately = createStately
// Enable lazy loading for code-split schemas
runtimeSchemas: () => import('./generated/schemas.runtime').then(m => m.RUNTIME_SCHEMAS),
});
`
This is optional - if no schemas.runtime.ts was generated, you don't need this option.
`typescript
import { createStately } from '@statelyjs/schema';
import { filesPlugin } from '@statelyjs/files';
const stately = createStately
.withPlugin(filesPlugin());
// Plugin utilities are now available
stately.plugins.files.utils.formatPath('/some/path');
`
Combines your generated types into a schema configuration:
`typescript`
type MyConfig = DefineConfig<
components, // OpenAPI components
DefinePaths
DefineOperations
typeof PARSED_SCHEMAS // Generated schema nodes
>;
Declares a plugin's type augmentations:
`typescript`
type MyPlugin = DefinePlugin<
'my-plugin', // Unique name (string literal)
MyNodes, // Node map
MyTypes, // Additional types
MyData, // Data utilities
MyUtils // Utility functions
>;
`typescript
import type { Schemas } from '@statelyjs/schema';
// Get the StateEntry union (entity type names)
type StateEntry = MySchemas['config']['components']['schemas']['StateEntry'];
// Get entity data types
type EntityData = MySchemas['types']['EntityData'];
// Get all nodes from plugins
type AllNodes = MySchemas['plugin']['AnyNode'];
`
The @statelyjs/codegen CLI generates the files this package consumes:
`bash`
pnpx @statelyjs/codegen ./openapi.json ./src/generated
This produces:
- types.ts - TypeScript interfaces matching your OpenAPI specschemas.ts
- - Parsed PARSED_SCHEMAS object for runtime use
`typescript
import type { ValidationResult } from '@statelyjs/schema';
const result: ValidationResult = stately.utils.validate(data, 'Pipeline');
if (!result.valid) {
console.log(result.errors);
// [{ path: ['name'], message: 'Required field missing' }]
}
`
Creates a Stately schema runtime.
Type guard for checking node types:
`typescript``
if (isNodeOfType(node, NodeType.Primitive)) {
// node is typed as Primitive
}
Creates typed API operation bindings from paths.
Apache-2.0