Reference for generating Markdown documents with require("markdown").builder().
Use the Markdown builder when JavaScript has structured data and needs to emit a clean Markdown document. The builder avoids brittle string concatenation by giving scripts typed operations for headings, paragraphs, lists, checklists, callouts, code blocks, raw blocks, tables, and inline formatting.
The builder is Go-backed. JavaScript calls exported Go methods such as Title, Paragraph, Table, RenderString, and RenderHTML. Rendered results expose exported Go fields such as Text, Bytes, and Blocks.
Load the existing markdown module and create a builder. The builder is part of require("markdown"); there is no separate module name.
const markdown = require("markdown");
const text = markdown.builder()
.Title("Status report")
.Paragraph("Generated from structured data.")
.RenderString();
Use this API when the document shape is assembled programmatically. Use the template module when the document shape is fixed and mostly described by a template file.
A MarkdownBuilder starts empty. Each block method appends one Markdown block and returns the same builder so calls can be chained.
const doc = markdown.builder()
.Title("Release notes")
.Paragraph("This release contains generated sections.")
.Heading(2, "Changes")
.BulletList(["Added builder API", "Added table rendering"]);
const result = doc.Render();
console.log(result.Text);
console.log(result.Bytes);
console.log(result.Blocks);
Call Validate() when a script wants to inspect errors without rendering. Call Render() for a structured result, RenderString() for only Markdown text, and RenderHTML() to pass the generated Markdown through goldmark.
Adds a level-one heading. This is equivalent to Heading(1, text).
markdown.builder().Title("Project report");
Adds a heading from level 1 through 6. Invalid levels are recorded as validation errors and fail rendering.
markdown.builder()
.Heading(2, "Implementation")
.Heading(3, "Tests");
Adds a paragraph. Ordinary strings are escaped as Markdown text. Multiple parts are concatenated, so inline helper values can be mixed with strings.
const i = markdown.inline();
markdown.builder()
.Paragraph("Run ", i.Code("go test ./..."), " before committing.");
Text(text) is convenience sugar for a one-part paragraph.
Adds trusted raw Markdown as a block. Use this for advanced Markdown that the builder does not model yet. Do not use it for untrusted user input.
markdown.builder()
.Raw("<details>\n<summary>More</summary>\n\nRaw Markdown here.\n</details>");
Adds a thematic break rendered as ---.
markdown.builder()
.Paragraph("Before")
.ThematicBreak()
.Paragraph("After");
Adds a blockquote. String bodies are split on newlines and every line receives the > prefix.
markdown.builder()
.Blockquote("This text is quoted.\nSo is this line.");
Adds an Obsidian-style callout block. The kind is uppercased in the marker.
markdown.builder()
.Callout("warning", "Review needed", "Check table escaping before release.");
Output:
> [!WARNING] Review needed
> Check table escaping before release.
Adds a bullet list from a JavaScript array.
markdown.builder()
.BulletList(["Parse data", "Build report", "Upload PDF"]);
Adds an ordered list. The optional start value defaults to 1 and must be positive.
markdown.builder()
.OrderedList(["Design", "Implement", "Review"], 1);
Adds a GitHub-style task list. Items may be strings or objects with text and checked fields.
markdown.builder()
.Checklist([
{ text: "Service layer", checked: true },
{ text: "CLI docs", checked: false },
]);
Adds a fenced code block. The renderer chooses a fence long enough to contain code that itself includes backticks.
markdown.builder()
.CodeBlock("js", "console.log('hello');");
The language name must not contain whitespace.
Starts a TableBuilder. A table is appended only when End() is called.
markdown.builder()
.Table()
.Columns("Name", "Status")
.Row("Parser", "done")
.Row("Builder", "planned")
.End()
.RenderString();
Tables are first-class because they are easy to get wrong by hand. The renderer escapes pipes in cells, turns cell newlines into <br>, pads columns for readable source output, and validates that every row has the same number of cells as the header.
Sets the table columns. Each column can be a string or an object with label and optional align.
.Table()
.Columns(
{ label: "Name", align: "left" },
{ label: "Score", align: "right" },
"Notes"
)
Supported alignments are default, left, center, and right.
Updates alignments after columns are set.
.Table()
.Columns("Name", "Score")
.Align("left", "right")
Adds one row. Cells can be strings, numbers, booleans, inline helper values, or arrays of inline parts.
const i = markdown.inline();
.Table()
.Columns("Function", "Description")
.Row(i.Code("builder()"), "Create a document builder")
Adds multiple rows from an array of arrays.
.Table()
.Columns("Name", "Status")
.Rows([
["Parser", "done"],
["Builder", "planned"],
])
Appends the table to the parent document and returns the MarkdownBuilder. Call End() once before continuing with more document blocks.
markdown.builder()
.Table()
.Columns("Name", "Status")
.Row("Parser", "done")
.End()
.Heading(2, "After the table");
Calling table methods after End() records validation errors.
Call markdown.inline() to create explicit inline nodes. Use inline helpers when ordinary escaped strings are not enough.
const i = markdown.inline();
Creates escaped text.
i.Text("literal *stars*")
Creates trusted raw inline Markdown. Use sparingly and never for untrusted data.
i.Raw("<kbd>Ctrl</kbd> + <kbd>C</kbd>")
Creates a code span with safe backtick fencing.
i.Code("go test ./...")
Creates emphasis and strong emphasis.
markdown.builder()
.Paragraph("Status: ", i.Strong("complete"));
Creates a Markdown link.
i.Link("docs", "https://example.com/docs", "Documentation")
Render() returns a Go-backed result object.
const result = markdown.builder().Title("Report").Render();
console.log(result.Text); // rendered Markdown
console.log(result.Bytes); // byte length of Text
console.log(result.Blocks); // number of document blocks
RenderString() returns only result.Text. RenderHTML() renders the generated Markdown through the same goldmark path used by markdown.renderHTML(input).
The builder accumulates structural errors and reports them during Validate(), Render(), RenderString(), or RenderHTML().
Common validation failures include:
End().Example:
const result = markdown.builder()
.Heading(9, "bad")
.Table().Columns("A", "B").Row("only one cell").End()
.Validate();
if (!result.Valid) {
console.error(result.Errors.join("\n"));
}
This example generates a small report with a table, checklist, and inline code.
const markdown = require("markdown");
const i = markdown.inline();
const rows = [
{ name: "Service layer", status: "done", owner: "Ada" },
{ name: "Goja module", status: "done", owner: "Linus" },
{ name: "Docs", status: "review", owner: "Intern" },
];
const table = markdown.builder()
.Title("Markdown Builder Report")
.Paragraph("Generated by ", i.Code('require("markdown").builder()'), ".")
.Table()
.Columns(
{ label: "Name", align: "left" },
{ label: "Status", align: "center" },
{ label: "Owner", align: "left" }
);
for (const row of rows) {
table.Row(row.name, row.status, row.owner);
}
const output = table.End()
.Heading(2, "Next steps")
.Checklist([
{ text: "Run tests", checked: true },
{ text: "Review generated Markdown", checked: false },
])
.RenderString();
console.log(output);
The generated binary bundles example data for the builder API.
./dist/goja-text markdown builder-examples
./dist/goja-text markdown builder-example report
./dist/goja-text markdown builder-example api-table
./dist/goja-text markdown builder-example report --output-path report.md
These commands are examples of using the JavaScript API from jsverbs. They are not required when writing normal scripts; scripts can call require("markdown").builder() directly.
| Problem | Cause | Solution |
|---|---|---|
RenderString() throws a validation error | The builder recorded an invalid heading, list, table, or code-block option | Call Validate() before rendering and inspect Errors |
| Table rows fail validation | A row has fewer or more cells than the header | Ensure every Row() has exactly the same cell count as Columns() |
| The table does not appear in output | Table() returns a child builder and End() was not called | Call End() once before rendering or adding more parent blocks |
| Pipes appear to break table cells | Raw Markdown was used inside table cells | Prefer ordinary strings or inline().Code() so the renderer can escape ` |
| Markdown is visually wrapped in a table in CLI output | Glazed renders returned strings as a value field | Use --output-path or call the API from a script when raw Markdown output is needed |
Lowercase fields such as result.text are undefined | Results are Go-backed objects | Use PascalCase fields such as result.Text, result.Bytes, and result.Blocks |
goja-text-markdown-api-reference for parsing, traversal, validation, and HTML rendering.goja-text-markdown-user-guide for the broader Markdown module workflow.goja-text-template-api-reference when a fixed template file is a better fit than programmatic document assembly.goja-text-template-writing-documentation for template-based documentation generation.