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

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/packages/@openmaic/dsl/src/slides.ts), [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/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/packages/@openmaic/dsl/src/validate.ts) and [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/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:

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:

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/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/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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →