EPUB OPF Explained: How Rune Studio Builds the Package File

The OPF is the package’s index and reading-order contract. It does not simply repeat a metadata form. It declares bibliographic values, assigns identifiers to resources, and tells a reading system which of those resources belong in the spine. To review an EPUB OPF generated by Rune Studio, follow a chapter from the saved input to a manifest item, then from that item ID into the spine and navigation.

STUDIO-265 uses four synthetic chapters and no images. The exported package has four navigation links, four NCX points, seven spine items, zero missing resources, and a valid local inspection. This article focuses on the graph that joins those facts, rather than repeating a generic export checklist.

Begin with four named source chapters

The source workspace contains chapter-01.md through chapter-04.md. Before export, record all four paths, their order, and whether each chapter belongs in the table of contents. The saved Rune settings also carry the title, creator, publisher, language ja, horizontal writing mode, and volume version 1.5.

These inputs answer different questions. Chapter selection determines which manuscript files are converted. Order determines the sequence in which their generated XHTML appears. The contents flag determines which chapters become navigation entries. Bibliographic settings populate metadata. Keeping the inputs in separate columns makes a missing chapter distinguishable from a missing title or wrong order.

The fixed test does not contain a cover or body image. That deliberate zero is a control: any image item appearing in the generated manifest would require an explanation rather than being accepted as harmless extra content.

Let Rune generate the archive instead of drafting OPF by hand

The retained command path created the workspace, saved series and volume settings, selected the four chapters, inspected the export plan, generated the EPUB, and then inspected the closed result. The output is studio-265-260903.090000.epub, with SHA-256 da531e6dca334c5050ba24b12671f438130dec27f1fd1c4b932443c54adb9b0d.

The export response confirms the operation completed, but it is not the OPF evidence. Open the resulting archive and read OEBPS/content.opf directly. Its SHA-256 is 7073a5e4a074c4e779ee063dc39dbb4844faad533dff6cdbe98d69d47a596493. Every count below belongs to that package digest and that OPF digest.

Editing the generated OPF by hand may produce a temporary archive that looks correct, but it no longer proves what Rune generates from the workspace. A durable correction changes the source selection or setting and creates another export.

Read metadata without claiming fields that are absent

The OPF metadata contains the STUDIO-265 test title, creator Rune CLI Evidence, language ja, publisher Publisher-265, a generated identifier, date, and format. These values can be compared with the saved series inputs. They establish that Rune serialized the core bibliographic fields into the package.

The saved volume version was 1.5, but the literal version is not present in this fixed OPF. The review must preserve that boundary. It may say that 1.5 was configured and returned by the volume operation; it may not say that an OPF version field was observed. Publication and retailer display are separate questions as well.

When metadata is wrong, identify the originating setting, change only that setting, and regenerate. Do not infer that manifest or spine must also be wrong, but recheck them in the new output because the digest has changed.

Walk the manifest as a declaration table

The manifest declares the stylesheet; p001 through p004; title, navigation, and colophon XHTML; and the NCX. Each declaration binds an ID to an href and media type. The navigation item also carries the nav property. There are no image items in this fixture.

A manifest entry answers “is this resource declared?” It does not answer “where is it read?” A declared chapter can be absent from the spine. Conversely, a spine reference whose ID does not exist in the manifest is broken even if an XHTML file happens to sit in the ZIP.

For each chapter row, resolve the manifest href and verify that Text/p001.xhtml through Text/p004.xhtml exist. Check title, navigation, colophon, stylesheet, and NCX the same way. Zero missing files is the acceptance value for this layer.

Derive the seven-item reading sequence from spine ID references

The spine contains seven item references: title, navigation, four chapters, and colophon. Translate every idref back through the manifest. The result should be title.xhtml, nav.xhtml, p001.xhtml, p002.xhtml, p003.xhtml, p004.xhtml, and colophon.xhtml in that order.

This is the central distinction in the package graph. The manifest declares resources, while the spine orders the reading sequence. If chapter three is declared but absent from the spine, adding another manifest item will not repair the order. Recovery returns to Rune’s selected chapter plan and creates a new archive.

The local fixture uses page-progression-direction="ltr" and horizontal writing mode. Those values are specific to this test. They should not be copied into a vertical Japanese project without a separate layout decision.

Cross-check four routes in NAV and NCX

The navigation document contains four links, and the NCX contains four navPoint elements. Their labels run from STUDIO-265 第1章 through 第4章, with destinations p001.xhtml through p004.xhtml. Resolve those routes and compare them with the four chapter resources already connected through manifest and spine.

This cross-check detects different classes of omission. A chapter can exist and appear in the spine yet be absent from the visible contents. A navigation link can exist yet point to the wrong XHTML. Counts of four, four, and four are useful only after each row has been joined to the same chapter.

The package has 12 ZIP entries, seven spine items, four nav links, four NCX points, zero images, and a local valid=true result. These are bounded fixture values, not universal EPUB totals.

Repair the earliest broken edge and export again

Suppose p003 exists in the manifest but the spine skips its ID. Preserve the rejected EPUB and identify the first broken edge: chapter selection to generated resource, resource ID to spine, or chapter flag to navigation. Correct that input in Rune and export under a new filename. Do not patch a downstream XML file to conceal an upstream selection error.

Reopen the entire new graph: metadata, all manifest targets, seven spine positions, four navigation routes, and four NCX routes. Recovery is complete only when the new digest explains the correction and all previously accepted edges still pass.

The retained inspection does not prove retailer acceptance, identical presentation in every reader, or serialization of version 1.5 into OPF. Those remain explicit boundaries. The W3C EPUB 3.3 specification defines the package structures, while Rune Studio’s supported workflow is described on the official site. Keeping the source graph and generated graph connected is what makes the package review repeatable.