# What Is the Purpose of the @openmaic/dsl Package? Understanding OpenMAIC's Contract Foundation

> Explore the purpose of the @openmaic/dsl package. Discover its role in providing TypeScript definitions, runtime validation, and schema migration for a consistent OpenMAIC data language.

- Repository: [MAIC/OpenMAIC](https://github.com/THU-MAIC/OpenMAIC)
- Tags: deep-dive
- Published: 2026-08-31

---

**The `@openmaic/dsl` package serves as the contract keystone of the OpenMAIC ecosystem, providing zero-dependency TypeScript definitions for slide objects alongside runtime validation, normalization utilities, and schema migration tools that ensure all SDK packages speak a consistent data language.**

The OpenMAIC project is a modular SDK for building interactive presentation applications. At its core sits the `@openmaic/dsl` package, which isolates the pure data contract—the shape of slides, stages, scenes, and actions—from any rendering or storage implementation. This architectural separation allows renderers, importers, and storage adapters to depend on a single source of truth without pulling in heavy runtime dependencies like React or PPTX libraries.

## Architectural Purpose: The Contract Keystone

The primary purpose of `@openmaic/dsl` is to **isolate the data contract** from implementation details. By containing only the pure specification of the slide-object model, it acts as the single source of truth for the entire SDK family. Because it maintains **zero runtime dependencies**, any package—whether a React renderer, a PPTX importer, or a cloud storage adapter—can import these definitions without bloating their bundle with extraneous libraries.

This design philosophy ensures that producers can validate input data, consumers can trust the shape of incoming documents, and the system can evolve through versioned migrations without breaking existing integrations.

## Three Core Responsibilities

The package fulfills three tightly-coupled architectural responsibilities that collectively define the purpose of `@openmaic/dsl`.

### 1. Canonical Object-Model Definitions

The foundation of the package is the type system defined in [[`src/slides.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src/slides.ts)](https://github.com/THU-MAIC/OpenMAIC/blob/main/packages/@openmaic/dsl/src/slides.ts), [[`src/stage.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src/stage.ts)](https://github.com/THU-MAIC/OpenMAIC/blob/main/packages/@openmaic/dsl/src/stage.ts), and [[`src/action.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src/action.ts)](https://github.com/THU-MAIC/OpenMAIC/blob/main/packages/@openmaic/dsl/src/action.ts). These files export the canonical interfaces and enums that describe the presentation model:

- **`Slide`** and **`PPTElement`** define the visual structure of individual slides
- **`Stage`** and **`Scene`** (with **`SceneType`** enum) represent the lesson skeleton and sequencing
- **`Action`** and its variants describe playback verbs and interactive behaviors

All other OpenMAIC packages import these same canonical types, guaranteeing that they all speak the same language when handling presentation data.

### 2. Runtime Validation and Normalization

Beyond static types, the package provides zero-dependency structural validators and normalizers in [[`src/validate.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src/validate.ts)](https://github.com/THU-MAIC/OpenMAIC/blob/main/packages/@openmaic/dsl/src/validate.ts) and [[`src/normalize.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src/normalize.ts)](https://github.com/THU-MAIC/OpenMAIC/blob/main/packages/@openmaic/dsl/src/normalize.ts):

- **`validateStage`**, **`validateScene`**, and **`validateAction`** perform runtime structural validation without requiring external validator libraries like Joi or Zod
- **`normalizeSlide`**, **`normalizeScene`**, and **`normalizeStage`** automatically fill default values and derive geometric properties, repairing malformed documents automatically

These utilities allow producers to **validate** input at runtime and **repair** incomplete data before it reaches rendering engines.

### 3. Schema Versioning and Migration

Forward compatibility is handled through [[`src/version.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src/version.ts)](https://github.com/THU-MAIC/OpenMAIC/blob/main/packages/@openmaic/dsl/src/version.ts), which exports:

- **`DSL_VERSION`**: The current contract version constant
- **`DSL_MIGRATIONS`**: An array of pure migration functions forming a version ladder
- **`migrate`**: A runner function that applies necessary transformations to bring old documents up to the current schema

When the on-disk contract evolves, this migration system updates legacy documents to the current shape in an idempotent, forward-compatible manner. Additionally, the package generates **JSON Schema** definitions at build time (via `ts-json-schema-generator`), enabling non-TypeScript consumers to validate data without importing TypeScript source code.

## Working with @openmaic/dsl: Code Examples

The following example demonstrates importing core types, validating a stage document, normalizing slide data, enumerating assets, and migrating legacy documents:

```typescript
import {
  // Core types
  type Slide, 
  type Action,
  type Stage,
  // Validation & normalization
  validateStage, 
  normalizeSlide,
  // Asset enumeration
  enumerateAssetManifest, 
  type AssetManifest,
  // Version handling
  DSL_VERSION, 
  migrate,
} from '@openmaic/dsl';

// 1️⃣ Validate a stage document structurally
const result = validateStage(myStage);
if (!result.valid) {
  console.error('Stage is invalid:', result.errors);
}

// 2️⃣ Normalize a raw slide (fills defaults, derives geometry)
const cleanSlide: Slide = normalizeSlide(rawSlide);

// 3️⃣ Enumerate all assets referenced by a document
const manifest: AssetManifest = enumerateAssetManifest(myStage, {
  metadata(ref, kind) {
    // Optional: attach extra metadata like size or mime type
    return { url: ref, kind };
  },
});

// 4️⃣ Migrate an old document to the current DSL version
const upToDateStage = migrate(oldStage);
console.log(`Migrated to DSL version: ${DSL_VERSION}`);

```

## Key Source Files and Entry Points

Understanding the purpose of `@openmaic/dsl` requires familiarity with its module structure:

- [[`src/index.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src/index.ts)](https://github.com/THU-MAIC/OpenMAIC/blob/main/packages/@openmaic/dsl/src/index.ts) — Public entry point that re-exports all core symbols
- [[`src/slides.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src/slides.ts)](https://github.com/THU-MAIC/OpenMAIC/blob/main/packages/@openmaic/dsl/src/slides.ts) — Defines the slide object model (`Slide`, `PPTElement`, `ElementTypes`)
- [[`src/stage.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src/stage.ts)](https://github.com/THU-MAIC/OpenMAIC/blob/main/packages/@openmaic/dsl/src/stage.ts) — Lesson skeleton definitions (`Stage`, `Scene`, `SceneType`)
- [[`src/action.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src/action.ts)](https://github.com/THU-MAIC/OpenMAIC/blob/main/packages/@openmaic/dsl/src/action.ts) — Playback verb set and action variants
- [[`src/validate.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src/validate.ts)](https://github.com/THU-MAIC/OpenMAIC/blob/main/packages/@openmaic/dsl/src/validate.ts) — Zero-dependency structural validators (`validateStage`, `validateScene`)
- [[`src/normalize.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src/normalize.ts)](https://github.com/THU-MAIC/OpenMAIC/blob/main/packages/@openmaic/dsl/src/normalize.ts) — Default-filling and geometry derivation utilities
- [[`src/version.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src/version.ts)](https://github.com/THU-MAIC/OpenMAIC/blob/main/packages/@openmaic/dsl/src/version.ts) — Contract version constant and migration ladder
- [[`src/asset-manifest.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src/asset-manifest.ts)](https://github.com/THU-MAIC/OpenMAIC/blob/main/packages/@openmaic/dsl/src/asset-manifest.ts) — Asset-enumeration logic for extracting media references from stages

## Summary

- **`@openmaic/dsl`** isolates the OpenMAIC data contract, ensuring all SDK packages share a consistent type system without runtime coupling
- The package maintains **zero runtime dependencies**, allowing it to be imported by renderers, importers, and storage layers without bundle bloat
- It provides **structural validation** via pure functions like `validateStage` and `normalizeSlide` that require no external validation libraries
- **Version migration** is handled through a pure functional ladder (`migrate`, `DSL_VERSION`, `DSL_MIGRATIONS`) that updates old documents idempotently
- **Cross-language support** is enabled through build-time JSON Schema generation, making the contract accessible to non-TypeScript consumers

## Frequently Asked Questions

### Why does `@openmaic/dsl` maintain zero runtime dependencies?

By avoiding runtime dependencies on frameworks like React or libraries like PPTX, the package ensures that any consumer—from a lightweight Node.js importer to a browser-based renderer—can depend on the core contract without installing unnecessary packages. This keeps bundle sizes minimal and prevents diamond dependency conflicts across the OpenMAIC monorepo.

### How does the validation system work without external libraries?

The validation logic in [[`src/validate.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src/validate.ts)](https://github.com/THU-MAIC/OpenMAIC/blob/main/packages/@openmaic/dsl/src/validate.ts) implements pure TypeScript functions that perform structural checks on objects at runtime. These functions verify object shapes, required fields, and type constraints without relying on schema validation libraries like Joi or Zod, maintaining the package's zero-dependency guarantee while providing immediate feedback on malformed data.

### What is the migration ladder and how does it ensure forward compatibility?

The migration ladder, defined in [[`src/version.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/src/version.ts)](https://github.com/THU-MAIC/OpenMAIC/blob/main/packages/@openmaic/dsl/src/version.ts), consists of the `DSL_MIGRATIONS` array and the `migrate` runner. When `DSL_VERSION` increments, new migration functions are appended to transform documents from previous versions to the latest schema. The `migrate` function applies these transformations sequentially in an idempotent manner, ensuring that old documents automatically upgrade to current specifications without manual intervention or breaking changes.

### Can developers use `@openmaic/dsl` in non-TypeScript projects?

Yes. While the package provides first-class TypeScript definitions, it also generates **JSON Schema** files at build time using `ts-json-schema-generator`. These schemas allow non-TypeScript environments—such as Python services, Go microservices, or pure JavaScript applications—to validate OpenMAIC documents against the same canonical contract without importing TypeScript source code, enabling true polyglot interoperability within the ecosystem.