Configuration file
A project can include a .twain-md.json file to tell Twain how to render its documents. It
currently has one setting: the component map.
Schema
{
"componentMap": "docusaurus"
}
componentMap is either:
-
the name of a built-in framework map:
"docusaurus","mintlify","nextra", or"fumadocs"; or -
an object mapping your own component names to built-in kinds. A map is consulted only after Twain's own components and intrinsic HTML, so an entry can rescue a name Twain does not recognise but cannot change how a name it already renders behaves (
Note,Tabs,Card,Detailsand the rest):{"componentMap": {"Admonition": "callout","TabItem": "tab"}}
The available kinds are callout (and coloured variants such as callout:warning), tabs, tab,
steps, step, card, cardgroup, details, summary, figure, figcaption, and fragment.
Any other value is ignored. A configuration file cannot introduce new HTML tags, attributes, or
URLs, so it can never make a document less safe to open.
There are no other keys. Reading appearance such as theme and font is chosen per reader in the app, not in this file.
Where it goes, and how it is found
Where Twain looks for .twain-md.json depends on the tool:
| Tool | Where it looks |
|---|---|
| The app | Only the document's own folder, whether or not a folder is open. A .twain-md.json higher up the tree is not read, so a project that keeps one config at its root needs a copy beside the documents it should apply to. The app re-renders the document when this file changes, so edits take effect immediately. On the Mac App Store edition the sandbox only reaches files in a folder you have opened, so a config sitting beside a single opened file is applied once you open its enclosing folder; the direct download reads it straight away. |
| Quick Look | Only the document's own folder. The preview is sandboxed, so the read can be refused for a given file; when that happens the preview renders without a map rather than failing. |
| The CLI | The document's folder, then upward through parent folders, stopping at the document's repository root or the working directory, whichever is higher. With neither to bound it, the search stays in the document's own folder. A --component-map option overrides this. |
| The MCP server | It does not read this file. Pass a built-in map name as the componentMap tool argument instead; custom object maps and file paths are not accepted there. |
A malformed file is ignored rather than treated as an error, so a typo will not stop a document from
rendering; it just means no component map is applied. An oversized file is skipped the same way,
unread: the app and Quick Look take at most 64 KB, the CLI at most 1 MB. In the CLI, the first
.twain-md.json found ends the search even when it has no componentMap key, so a nearer file
without that key shadows a further one that has it.