Fill Word, PowerPoint and Excel templates

tplvane is an MIT-licensed template engine with one syntax for DOCX, PPTX and XLSX that treats every template and every piece of data as untrusted. ESM only, with two runtime dependencies (xlvane and fflate). It works with Uint8Array and has no Node.js dependencies; the command line needs Node.js.

npm install tplvane

Read the guideFill a template in the browserTemplate syntax

Quick start

import { readFileSync, writeFileSync } from 'node:fs';
import { render } from 'tplvane';

// offer.docx and logo.png are in examples/offer of the repository.
const result = render(readFileSync('offer.docx'), {
  logo: readFileSync('logo.png'),
  number: '2026/11/001',
  customer: { name: 'Anna Nowak', company: 'Nowak Design' },
  date: '2026-11-06',
  items: [{ name: 'Desk', qty: 1, price: 1200, total: 1200 }, { name: 'Chair', qty: 4, price: 349.99, total: 1399.96 }],
  sum: 2599.96,
  vip: true,
  notes: '**Delivery** in 5 working days.\n\n- Assembly included',
  author: 'Jan Kowalski',
}, { locale: 'pl-PL' });
writeFileSync('offer-anna.docx', result);

In the template: For {customer.name}, {customer.company}, a table row with {#items}{name} … {total | currency("EUR")}{/items}, {#vip}…{/vip}, the image {%logo} and the Markdown {~notes}. Nothing in a template can run code.

What it does

One syntax

Values {customer.name}, sections {#items}…{/items} that repeat for lists and show for true values, inverted sections, images {%logo} and Markdown {~notes}, the same in Word, PowerPoint and Excel.

inspect() and validate()

The tags of a template with their places, and a JSON Schema of the data it needs. validate lists every problem of the data with its path in the data and its place in the template, without writing a file.

What repeats

Follows from where the tags are: part of a paragraph, whole paragraphs, table rows, slides, or rows of a sheet. Tags are found however Word, PowerPoint, Excel or LibreOffice split their text.

Excel

Cells that hold one value keep its type; the formulas of repeated rows move with them, and totals, tables and filters below the copies grow to cover them.

Safe expressions

Comparisons, &&, ||, ! and allow-listed formatters such as currency, date and default. No eval, no access to prototypes, limits on iterations and output size.

Errors you can act on

Every error has a stable TV_E_* code, a place in the template and a hint; problems of a template or of data are reported all at once.

Command line

tplvane inspect, render, validate and preview, with --json output that follows documented schemas.

MCP server

@tplvane/mcp: tools for MCP clients to inspect templates, validate data, preview results, and with --allow-write to render, only inside the directories given at start.

From docxtemplater

The basic tags of docxtemplater are read as they are; the guide lists what works without changes, what needs a change and what is not available.

Inspect a template

import { readFileSync } from 'node:fs';
import { inspect } from 'tplvane';

const { tags, sections, schema } = inspect(readFileSync('offer.docx'));
for (const tag of tags) console.log(tag.raw, '-', tag.location.description);
// {%logo} - body, paragraph 1
// {number} - body, paragraph 2
// {customer.name} - body, paragraph 3
// …
// {#items} - body, table 1 row 2 cell 1, paragraph 1
console.log(JSON.stringify(schema, null, 2));

Command line

npx tplvane inspect offer.docx
npx tplvane validate offer.docx data.json
npx tplvane render offer.docx data.json
npx tplvane preview offer-filled.docx

The commands work on the offer template of the repository, examples/offer. The command line in 5 minutes explains each step.

Tested environments

The library is tested in Node.js 22, 24 and 26, and the built package is run in Bun, Deno and Chromium. Results are opened in LibreOffice in every test run.

Version 1.0.0. Changes are listed in the changelog.