Skip to content
Office Open

CORE

@office-open/core

Shared OOXML infrastructure — descriptors, validators, converters, charts, and SmartArt

@office-open/core is the shared infrastructure layer for @office-open/docx, @office-open/pptx, and @office-open/xlsx. You typically don't install it directly — but if you're building custom OOXML elements or extending the library, it provides all the building blocks.

#Module Overview

#Descriptor System

All OOXML XML parts are defined as descriptors — plain objects that declare how to stringify (JSON → XML) and parse (XML → JSON). The descriptor runtime lives in @office-open/core.

ts
import type { CustomDescriptor } from "@office-open/core";

const myPartDesc: CustomDescriptor<MyOptions> = {
  kind: "custom",
  stringify(value, ctx) {
    /* ...build XML string... */
  },
  parse(el, ctx) {
    /* ...read XML element into options... */
  },
};

Core provides CustomDescriptor<T> — every descriptor is custom, with hand-written stringify() and parse():

ts
// Serialize: Options → XML string
const xml = stringify(spacingDesc, { before: 240, after: 120 }, ctx);
// <w:spacing w:before="240" w:after="120"/>

// Parse: Element → Options
const opts = parse(spacingDesc, element, ctx);
// { before: 240, after: 120 }

#Values & Validation

Runtime validation functions for OOXML specification value types:

FunctionDescription
decimalNumber(val)Validates and floors to integer
hexColorValue(val)Validates hex color
twipsMeasureValue(val)TWIP measurement
hpsMeasureValue(val)Half-point measurement (font sizes)
percentageValue(val)Normalizes percentage string

#Unit Converters

ts
import {
  convertMillimetersToTwip,
  convertInchesToTwip,
  convertPixelsToEmu,
  convertEmuToPixels,
  convertPointsToEmu,
} from "@office-open/core";

convertMillimetersToTwip(25.4); // 1440 (1 inch)
convertPixelsToEmu(100); // 952500
convertPointsToEmu(12); // 152400

#Charts & SmartArt

The shared chart descriptor (chartSpaceDesc) and SmartArt components used by both @office-open/docx and @office-open/pptx.

#DrawingML

Shared primitives for colors, fills, outlines, effects, and geometry.

#Vector (VML)

The full structured VML vocabulary across the vml, office, word, excel, and presentation namespaces — shapes, strokes, text boxes, and legacy anchors used by text boxes, OLE objects, and cell comments.

#Password Hashing

All packages support plaintext password fields for document protection. The core crypto module implements ECMA-376 Agile Encryption with SHA-512:

ts
import { derivePasswordHash } from "@office-open/core";

// Auto-generates hashValue, saltValue, spinCount, algorithmName
const derived = derivePasswordHash("secret");
// { hashValue: "...", saltValue: "...", spinCount: 100000, algorithmName: "SHA-512" }

This is used internally by DOCX document protection, PPTX modify verifier, and XLSX sheet/workbook protection when a password field is provided.

The module also exports randomBytes(length) for generating cryptographically secure random bytes, and hashPasswordAgile(password, salt, spinCount) for computing the ECMA-376 Agile Encryption hash directly.

#Compilation & Packing

Shared ZIP compilation utilities used internally by generateDocument(), generatePresentation(), and generateWorkbook(). You typically call the top-level generate functions from each format package rather than using core directly:

ts
import { generateDocument } from "@office-open/docx";
import { generatePresentation } from "@office-open/pptx";
import { generateWorkbookSync } from "@office-open/xlsx";

// Async — returns cross-runtime Uint8Array by default
const bytes = await generateDocument(docOptions);
const blob = await generateDocument(docOptions, { type: "blob" });

// Sync variants are also available
const syncBytes = generateWorkbookSync(xlsxOptions);

Async methods use Web Workers for non-blocking DEFLATE. Sync methods block the main thread but avoid Worker overhead. Compression strategy matches Microsoft Office behavior: XML entries use DEFLATE (level 1, SuperFast); media is split by type — already-compressed formats (JPEG, PNG, GIF) use STORE, the rest (EMF/WMF/BMP/TIFF) use DEFLATE level 6 / Normal.