@office-open/core
@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.
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():
// 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:
| Function | Description |
|---|---|
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
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:
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:
import { generateDocument } from "@office-open/docx";
import { generatePresentation } from "@office-open/pptx";
import { generateWorkbookSync } from "@office-open/xlsx";
// Async — returns a Buffer (Node.js) or Blob (browser) by default
const buffer = await generateDocument(docOptions);
const blob = await generateDocument(docOptions, { type: "blob" });
// Sync variants are also available
const buf = 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.