Skip to content
Docxcelerate

Start Here

Document projects

The files that make up one document, what each is responsible for, and the config that surrounds them.

A workspace holds one document project per document. Each is a directory under documents/ with a single entrypoint, so a document can be moved, copied or reviewed as one thing.

Create one

dxcl document new tenancy-renewal --title "Tenancy Renewal"

Run it with no arguments to be asked for the name and title instead.

documents/tenancy-renewal/
  document.project.ts
  document.tsx
  document-style.ts
  preview-data.ts
  types.ts
  derivers/
    index.ts
  nodes/
    greeting.node.tsx
    intro.node.tsx
    index.ts

The split is the point. Each file answers one question:

FileWhat it holds
types.tsThe data contract — what a document needs to be written
preview-data.tsOne instance of that contract, for the preview
document.tsxStructure only: which nodes, in which sections, in which order
nodes/One component per node, plus an index.ts that exports them
document-style.tsFonts, spacing and margins for the packed .docx
derivers/index.tsNamed functions the engine runs per document
document.project.tsTies the above together and names the document

The entrypoint

import { defineDocumentProject } from "docxcelerate/document";
import { derivers } from "./derivers/index.ts";
import { documentTemplate } from "./document.tsx";
import { documentStyle } from "./document-style.ts";
import { previewData } from "./preview-data.ts";
import type { DocumentData } from "./types.ts";

export default defineDocumentProject<DocumentData>({
  id: "tenancy-renewal",
  name: "Tenancy Renewal",
  version: "0.1.0",
  template: documentTemplate,
  previewData,
  derivers,
  style: documentStyle,
  previewOptions: {
    availableTokens: 800,
  },
});
FieldWhat it decides
idHow the document is addressed, in artifacts and by an engine
nameWhat a person sees in the preview app
versionStamped into every artifact this project builds
templateThe tree, from document.tsx
previewDataWhat the preview resolves against
deriversValues computed per document rather than per build
styleThe style applied when packing
previewOptions.availableTokensThe budget useAvailableTokens reports

The preview app discovers projects by globbing for document.project.ts, so a new document appears in the picker as soon as it exists. Nothing registers it.

Keep the preview data honest

preview-data.ts is the only data most of a document will ever be built against, so it is worth more attention than it usually gets:

import type { DocumentData } from "./types.ts";

export const previewData: DocumentData = {
  recipientName: "Avery",
  city: "Berlin",
};

Short names and placeholder cities hide layout problems that real data exposes. Use the longest name and the largest figure you actually expect.

Workspace configuration

docxcelerate.config.json sits at the top of the workspace and covers every document in it. It stores named presets for build and upload behaviour:

{
  "schemaVersion": "docxcelerate.config/v0",
  "activePreset": "local",
  "presets": {
    "local": {
      "build": { "outDir": "build" },
      "upload": { "endpoint": "", "method": "POST", "headers": {}, "body": "document" }
    }
  }
}

activePreset selects which one applies, which is how a local setup and a staging engine sit side by side without editing configuration between runs. With upload.endpoint empty, everything still builds — you get artifacts on disk instead of a finished document.

Workspace and config documents every field, and build artifacts covers what a build writes.

Where to go next

  • Templates — computed structure, reusable pieces, and what changes when you publish
  • The engine — publishing a document and writing from it
  • Commands — every CLI flag

Edit this page on GitHub ↗