Contract

Public API

The exact module exports, config schema, CSS variable contract, comment marker format, and dev endpoints that are stable for 1.0. Everything outside this list is internal.

Stability promise

Once OpenPress 1.0 ships, the surfaces on this page are covered by semver: a breaking change to any listed export, config field, CSS variable, marker format, or dev endpoint requires a major version bump. Internal symbols and modules outside this list (anything reachable only via deep import) can change in any minor release without a CHANGELOG note about your downstream code breaking.

If something you're depending on isn't in this document and you'd like it to be, open an issue. Most promotions to public API are cheap — we mainly want them named.

@open-press/core

Top-level barrel of the React runtime and the Press Tree primitives.

ExportKindPurpose
Press component Document composition boundary. Render exactly one per press/index.tsx; put every page frame and document helper underneath it.
PressContext React context Low-level context for custom helper components. Normal workspaces and agents should use Press, Frame, MdxArea, and manuscript helpers instead.
PRESS_MARKER symbol Low-level identifier for wrapper tooling. Not needed when authoring documents.
Frame component Fixed page surface or nested region boundary. Required props: frameKey. Optional: role, chrome, className. All other props pass through to the underlying <section>. Page size is configured at the document level with config.page.
FRAME_MARKER symbol Identifier the renderer uses to detect Frame instances. Stable.
FrameContext React context Exposes the active frame's frameKey and the consumeArea(chainId) hook that MdxArea calls. Public so custom frame helpers can build on it.
MdxArea component A measurable content slot inside a frame. Required props: chainId. Optional: overflow ("extend" | "truncate"), className.
useSource hook Returns the resolved source registration for a given sourceId. Used by manuscript helpers and custom frame components.
BaseFigure, BaseCallout component Minimal figure / callout primitives. Workspace themes and starter skills build branded variants on top of these.
MediaFigure, ImageFigure component Figure that accepts src / alt / caption. Resolves media/... relative paths to /openpress/media/... automatically. ImageFigure is an alias of MediaFigure.

Types

Re-exported from the same barrel. Types are part of the public contract — if a field name changes, it's a breaking change.

  • FrameProps, MdxAreaProps, MdxAreaOverflow
  • PressProps, WorkspaceProps, PageGeometry, PressSource
  • BaseFigureProps, BaseCalloutProps, BaseCalloutKind
  • MediaFigureProps

@open-press/core/mdx

ExportKindPurpose
mdxSource(options) function Registers an MDX source tree. options.preset selects a discovery preset ("section-folders" for the standard chapters layout). options.root is the folder relative to press/.

@open-press/core/manuscript

Helpers for long-form, section-flow documents. Optional — skipping this module is fine for slide / social starters.

ExportKindPurpose
Sections component Iterates a registered source, emits one or more frames per section. Required: source. Optional: page (custom per-page component) — defaults to DefaultSectionPage. Optional: opener.
Chapters alias Identical to Sections. Provided for readability when source vocabulary uses "chapter".
DefaultSectionPage component The fallback page component Sections uses when no page prop is supplied.
Toc, TocArea component TOC frame + TOC content slot. TocArea measures and paginates the generated toc:<sourceId> chain.

Types

  • SectionsProps, SectionsPageProps, SectionsOpenerProps
  • ChaptersProps
  • TocProps, TocAreaProps, TocPageProps

@open-press/core/numbering

Caption / figure / table numbering formatters. Build-time helpers used by the renderer; public so custom theming can format labels consistently.

  • formatCaptionLabel(kind, index, options?) — produces the localized label string (Figure 1 / 圖 1 / etc.).
  • defaultCaptionLocale — the default locale config; reference value for config.captionNumbering.

@open-press/cli

Scaffolds a new workspace. The CLI does not fetch templates or external starters — its job is to copy the framework runtime, install framework agent skills, and write root workspace metadata. See init reference for the complete flag list.

npx @open-press/cli init <target> --title "…"

Opinionated starters live in skills. Install a skill with npx skills add <owner/repo>, then let the agent read that skill and copy or adapt its starter/example files into press/ or transitional document/.

Once inside the scaffolded workspace, the engine binary takes over via npm scripts (dev / build / preview / typecheck) and the openpress:-prefixed targets (pdf, deploy). See CLI overview.

Workspace config (package.json "openpress")

Operational settings live in the workspace's package.json under the "openpress" field — the only place the engine reads sync, before any React render. Everything else (title / page / sources / theme) lives on <Press> props in press/index.tsx. Full schema at Workspace config.

{
  "openpress": {
    "pdf":    { "filename": "..." },
    "deploy": { "adapter": "cloudflare-pages", "projectName": "...", "source": ".deploy" }
  }
}

Press Tree entry (press/index.tsx)

Default-exports a function component returning <Workspace> wrapping one or more <Press> children. The engine reads metadata (title, page, sources, slug, captionNumbering, theme, componentsDir) from <Press> props on the JSX tree at export time. There are no named exports — the entry is the JSX, period. Full schema at Press and Workspace.

CSS variables

Workspace themes and starter skills read and override these. Renames are breaking.

VariableSourceNotes
--openpress-page-width / --openpress-page-height Engine (from config.page) CSS length. Page geometry pushed into measurement + runtime.
--openpress-page-aspect-ratio / --openpress-page-height-ratio Engine Derived ratios for fluid scaling (zoom control, fit-page mode).
--openpress-page-viewport-scale Runtime (workbench) Current page-zoom multiplier. Set by the page-zoom control.
--openpress-page-padding-top / -x / -bottom Workspace theme tokens.css Per-workspace page padding. Consumed by theme/base/page-contract.css.
--openpress-page-body-gap Workspace theme tokens.css Vertical gap between blocks inside MdxArea.

A workspace theme or starter skill may define additional color / typography tokens in its own tokens.css. Those names are local conventions, not framework contract — the framework only cares about the page-geometry / page-padding / page-body-gap names above.

Comment markers (@openpress-comment)

The inspector writes inline comments into source MDX/TSX files as a stable, parseable marker. Format:

{/* @openpress-comment id=<short-id> ts=<iso-timestamp> hint=<url-encoded> note=<url-encoded> */}

Field semantics:

  • id — short hex id for cross-referencing. Required.
  • ts — ISO 8601 timestamp of when the marker was inserted. Required.
  • hint — URL-encoded inspector metadata (placement, target object id). Optional.
  • note — URL-encoded note text. Required.

Discovery via rg "@openpress-comment" document -n; programmatic listing via listCommentMarkers exported from engine/react/comment-marker.mjs. The openpress-apply-comments skill is the canonical owner of the apply / clear / verify flow.

Dev endpoints

Available only in dev mode (npm run dev). Wired into the Vite middleware in the bundled template's vite.config.ts. Path prefix: /__openpress.

PathMethodPurpose
/openpress/document.jsonGETThe full rendered document — fetched by OpenPressApp on mount and after inline edits.
/__openpress/statusGETDeployment status snapshot.
/__openpress/commentPOST / GET / PATCH / DELETESubmit, list, update, or clear comment markers. Used by the inspector.
/__openpress/searchGETFull-text search across registered MDX sources.
/__openpress/source-editGET / POSTRead raw source text or apply an inline source edit (text block, table cell, caption).
/__openpress/project-assetPOSTProject preview actions (legacy — kept for compatibility, dialog is view-only in 0.9+).
/__openpress/deployPOSTRun the configured deploy adapter. Requires confirmation.
/__openpress/local-pdf-exportPOSTGenerate a local PDF.
/__openpress/local-pdf-fileGETServe the most recent local PDF.

Internal — do not depend on

The following are reachable but explicitly not stable for 1.0:

  • Deep imports under @open-press/core/openpress/* or any path not listed in the package exports map. Use the barrels (/app, /document-model, /reader, /shared, /workbench) or the top-level entry.
  • engine/react/pagination.mjs exports paginateMeasuredBlocks as a legacy wrapper around the region allocator. Pending deprecation; the region allocator (allocateBlocksToRegions, pagesFromRegions) is the long-term API.
  • document-model/objectEntityModel — id encoding (mdx-block:..., mdx-area:..., page:...) is observable in HTML but the exact format may be refined for cell / nested entities.
  • Workbench internals (HtmlWorkbench internal hooks, InlineInspectorLayer props, panel registry shape). The shell composes these but they aren't intended for external consumption.
  • Engine CLI internals — use the npm run openpress:* scripts rather than reaching into engine/commands/*.
Promoting an internal to public. If you've shipped against an internal symbol and want it covered by semver, the path is short: open an issue with the use case, we audit the surface, and it lands in this page in the next release.