### Install Dependencies
Source: https://github.com/lukeed/tempura/blob/master/examples/worker/readme.md
Installs the necessary project dependencies.
```sh
$ npm install
```
--------------------------------
### Install Tempura
Source: https://github.com/lukeed/tempura/blob/master/readme.md
Install the tempura package using npm. This is the first step to using the template engine in your project.
```bash
$ npm install --save tempura
```
--------------------------------
### Tempura Template Example (example.hbs)
Source: https://github.com/lukeed/tempura/blob/master/readme.md
This is an example of a Tempura template file using Handlebars-like syntax. It demonstrates conditional rendering, variable assignment, and iteration.
```hbs
{{! expected props to receive }}
{{#expect title, items }}
{{! inline variables }}
{{#var count = items.length }}
{{#var suffix = count === 1 ? 'task' : 'tasks' }}
{{#if count == 0}}
You're done! 🎉
{{#else}}
You have {{{ count }}} {{{ suffix }}} remaining!
{{#if count == 1}}
Almost there!
{{#elif count > 10}}
... you must be fried 😔
{{#else}}
You've got this 💪🏼
{{/if}}
{{#each items as todo}}
{{ todo.text }}
{{/each}}
{{/if}}
```
--------------------------------
### Tempura Template Syntax Example
Source: https://context7.com/lukeed/tempura/llms.txt
Demonstrates basic Tempura template syntax for variable expectation, inline computation, conditional rendering, iteration, and output escaping. Use for standard template logic.
```handlebars
{{! Declare all required props }}
{{#expect user, todos, showDone}}
{{! Inline computed variable }}
{{#var total = todos.length}}
{{#var done = todos.filter(t => t.done).length}}
{{#var pending = total - done}}
{{ user.name }}'s Tasks
{{{ pending }}} of {{{ total }}} remaining
{{! Conditional rendering }}
{{#if total === 0}}
No tasks yet — enjoy your day!
{{#elif pending === 0}}
All done! 🎉
{{#else}}
{{#each todos as todo, idx}}
{{#if !todo.done || showDone}}
{{/if}}
{{! Raw output — not HTML-escaped }}
{{!
Multi-line template comments are removed from output entirely.
HTML comments like are preserved.
!}}
```
--------------------------------
### Basic Expression and Variable Usage
Source: https://github.com/lukeed/tempura/blob/master/docs/syntax.md
Use double curly braces {{ }} to print values. This example shows printing a 'name' variable and accessing a property 'length' of an 'items' array.
```handlebars
{{#expect name}}
Hello, {{ name }}!
```
```handlebars
Items left: {{ items.length }}
```
--------------------------------
### Iterate Over Arrays with #each (Value Only)
Source: https://github.com/lukeed/tempura/blob/master/docs/syntax.md
Use the `#each` helper to loop over an array. This example demonstrates how to access only the value of each item in the array.
```handlebars
{{#expect items}}
{{! only use the value }}
{{#each items as item}}
{{ item.title }}{{ item.text }}
{{/each}}
```
--------------------------------
### Async Compile with Custom Async Block
Source: https://context7.com/lukeed/tempura/llms.txt
Demonstrates compiling a template with an asynchronous custom block using the `async: true` option. The custom block simulates an asynchronous data fetch.
```javascript
import { compile } from 'tempura';
const asyncRender = compile(`
{{#expect symbol}}
{{#ticker symbol=symbol }}
`, {
async: true,
blocks: {
async ticker(args) {
// Simulate async data fetch
const price = await Promise.resolve('182.34');
return `${args.symbol}: $${price}`;
}
}
});
const result = await asyncRender({ symbol: 'AAPL' });
console.log(result); //=> "AAPL: $182.34"
```
--------------------------------
### Library Load Time Comparison
Source: https://github.com/lukeed/tempura/blob/master/bench/readme.md
Measures the time taken to require each templating library. Lower values indicate faster initialization.
```text
pug: 127.647ms
ejs: 1.444ms
handlebars: 23.627ms
yeahjs: 0.979ms
dot: 1.363ms
art-template: 8.847ms
tempura: 0.593ms
```
--------------------------------
### Template Compile Time Comparison
Source: https://github.com/lukeed/tempura/blob/master/bench/readme.md
Shows the average time in milliseconds to parse a template and generate its function equivalent. Results are an average of 5 runs.
```text
Benchmark (Compile)
~> pug 7.20474ms
~> handlebars 0.02952ms
~> ejs 0.28859ms
~> yeahjs 0.12206ms
~> dot 0.27055ms
~> art-template 0.76982ms
~> tempura 0.19813ms
```
--------------------------------
### Run Rollup Build
Source: https://github.com/lukeed/tempura/blob/master/examples/worker/readme.md
Executes the Rollup build process to bundle the project. The configuration is managed in `rollup.config.js`.
```sh
$ npm run rollup
```
--------------------------------
### Run esbuild Build
Source: https://github.com/lukeed/tempura/blob/master/examples/worker/readme.md
Executes the esbuild build process. This can be run using the npm script or directly with Node.js. The programmatic approach is required to attach esbuild plugins.
```sh
$ npm run esbuild
```
```sh
$ node esbuild.js
```
--------------------------------
### Define Global Props with options.props
Source: https://context7.com/lukeed/tempura/llms.txt
Explains how to use `options.props` to declare shared/global variables programmatically, serving as a programmatic alternative to `#expect`. Use for context like `user`, `config`, or `locale` available in all templates.
```javascript
import { compile } from 'tempura';
// Without options.props, every template needs: {{#expect user, locale}}
// With options.props, these are globally available:
const globalOptions = {
props: ['user', 'locale'],
};
const headerRender = compile(`
Hello, {{ user.name }} ({{ locale }})
`, globalOptions);
const footerRender = compile(`
`, globalOptions);
const ctx = { user: { name: 'Alice', org: 'ACME' }, locale: 'en-US' };
console.log(headerRender(ctx)); //=> "Hello, Alice (en-US)"
console.log(footerRender(ctx)); //=> ""
// Per-template #expect still works alongside props (deduped automatically)
const pageRender = compile(`
{{#expect title}}
{{ title }} | {{ user.org }}
`, globalOptions);
console.log(pageRender({ ...ctx, title: 'Dashboard' }));
//=> "Dashboard | ACME"
```
--------------------------------
### Write Transformed Template to File
Source: https://context7.com/lukeed/tempura/llms.txt
Shows how to write the transformed JavaScript function string to a file, enabling it to be imported directly as a render function during the build process.
```javascript
import { transform } from 'tempura';
import { writeFile } from 'fs/promises';
const template = `
{{#expect user}}
Hello, {{ user.name }}! You have {{{ user.msgCount }}} messages.
`;
const esm = transform(template);
// Write to disk for bundling (e.g., as part of a build step)
await writeFile('template.js', esm, 'utf8');
// The output file can now be imported directly as a render function:
// import render from './template.js';
// render({ user: { name: 'Alice', msgCount: 5 } });
```
--------------------------------
### tempura.compile(input, options?)
Source: https://github.com/lukeed/tempura/blob/master/docs/api.md
Converts a template string into an executable function that renders the template.
```APIDOC
## tempura.compile(input, options)
### Description
Compiles a template string into a renderable function. The returned function can generate a string or a Promise of a string.
### Parameters
#### Path Parameters
- **input** (string) - Required - The template string to compile.
- **options** (object) - Optional - Configuration options for compilation.
- **options.escape** (function) - Optional - The function to use for escaping `{{{ raw }}}` values. Defaults to `tempura.esc`.
### Returns
- `Compiler` - A function that takes data and returns the rendered template string or a Promise of a string.
```
--------------------------------
### tempura.compile(input, options?)
Source: https://context7.com/lukeed/tempura/llms.txt
Converts a template string into a reusable render function. This is the primary API for server-side rendering and runtime use.
```APIDOC
## tempura.compile(input, options?)
### Description
Parses the template and returns a `Compiler` function. When invoked with the appropriate data object, the function returns a `string` (or `Promise` if `options.async` is true).
### Method
`compile(input: string, options?: object)`
### Parameters
#### Input
- `input` (string) - The template string to compile.
- `options` (object, optional) - Configuration options for compilation.
- `async` (boolean) - If true, the render function will return a `Promise` to support async blocks.
- `escape` (function) - A custom function for HTML escaping.
- `blocks` (object) - An object mapping custom block names to their implementations (can be sync or async).
### Request Example
```javascript
import { compile } from 'tempura';
const render = compile(`
{{#expect name, items}}
"
```
### Response
- Returns a render function.
```
--------------------------------
### Define Custom Directives with options.blocks
Source: https://github.com/lukeed/tempura/blob/master/docs/api.md
Configure custom directives like `foo` and `hello123` for use in templates. Ensure all used directives are defined to avoid parsing errors. The `hello123` directive is defined as asynchronous.
```javascript
/**
* @type {tempura.Options}
*/
let options = {
async: true,
blocks: {
foo(args) {
return `foo got ~${args.value}~`;
},
async hello123(args) {
return `
hello123 got ~${args.name}~
`;
}
}
};
let template = `
{{#foo value=123 }}
{{#hello123 name="world" }}
`;
// NOTE: Works with `transform` too
await tempura.compile(template, options)();
//=> "foo got ~123~
hello123 got ~world~
"
```
--------------------------------
### Compile Template to Render Function (Basic Usage)
Source: https://context7.com/lukeed/tempura/llms.txt
Use `compile()` to convert a template string into a reusable render function for runtime use. Ensure all expected variables are provided when invoking the render function.
```javascript
import { compile } from 'tempura';
// Basic usage
const render = compile(`
{{#expect name, items}}
{{#var count = items.length}}
"
```
--------------------------------
### Render Tempura Template (render.js)
Source: https://github.com/lukeed/tempura/blob/master/readme.md
This JavaScript code demonstrates how to read a Tempura template file and render it with provided data. It uses the `compile` function for runtime rendering.
```js
import { readFile } from 'fs/promises';
import { transform, compile } from 'tempura';
const template = await readFile('example.hbs', 'utf8');
// Transform the template into a function
// NOTE: Produces a string; ideal for build/bundlers
// ---
let toESM = transform(template);
console.log(typeof toESM); //=> "string"
console.log(toESM);
//=> `import{esc as $$1}from"tempura";export default function($$3,$$2){...}`
let toCJS = transform(template, { format: 'cjs' });
console.log(typeof toCJS); //=> "string"
console.log(toCJS);
//=> `var $$1=require("tempura").esc;module.exports=function($$3,$$2){...}`
// Convert the template into a live function
// NOTE: Produces a `Function`; ideal for runtime/servers
// ---
let render = compile(template);
console.log(typeof render); //=> "function"
render({
title: 'Reminders',
items: [
{ id: 1, text: 'Feed the doggo' },
{ id: 2, text: 'Buy groceries' },
{ id: 3, text: 'Exercise, ok' },
]
});
//=> "
You have 3 tasks remaining!
\n"
//=> + "You've got this 💪🏼\n\n"
//=> + "
\n"
//=> + "
Feed the doggo
\n"
//=> + "
Buy groceries
\n"
//=> + "
Exercise, ok
\n"
//=> + "
"
```
--------------------------------
### Render Time - Raw Values Benchmark
Source: https://github.com/lukeed/tempura/blob/master/bench/readme.md
Measures how quickly generated functions render an output string without escaping template values. Higher ops/sec indicates better performance.
```text
Validation (Render)
✔ pug
✔ handlebars
✔ ejs
✔ yeahjs
✔ dot
✔ art-template
✔ tempura
Benchmark (Render)
pug x 34,847 ops/sec ±2.79% (93 runs sampled)
handlebars x 6,700 ops/sec ±1.41% (92 runs sampled)
ejs x 802 ops/sec ±0.54% (94 runs sampled)
yeahjs x 31,508 ops/sec ±0.30% (97 runs sampled)
dot x 40,704 ops/sec ±3.08% (93 runs sampled)
art-template x 39,839 ops/sec ±0.86% (90 runs sampled)
tempura x 44,656 ops/sec ±0.42% (92 runs sampled)
```
--------------------------------
### Tempura Benchmark Results
Source: https://github.com/lukeed/tempura/blob/master/readme.md
These are benchmark results comparing Tempura's rendering performance against other template engines, both with raw and escaped values. For full details, refer to the `/bench` directory.
```text
Benchmark: Render w/ raw values (no escape)
pug x 34,847 ops/sec ±2.79% (93 runs sampled)
handlebars x 6,700 ops/sec ±1.41% (92 runs sampled)
ejs x 802 ops/sec ±0.54% (94 runs sampled)
dot x 40,704 ops/sec ±3.08% (93 runs sampled)
art-template x 39,839 ops/sec ±0.86% (90 runs sampled)
tempura x 44,656 ops/sec ±0.42% (92 runs sampled)
Benchmark: Render w/ escaped values
pug x 2,800 ops/sec ±0.31% (95 runs sampled)
handlebars x 733 ops/sec ±0.34% (94 runs sampled)
ejs x 376 ops/sec ±0.17% (91 runs sampled)
dot x 707 ops/sec ±0.15% (96 runs sampled)
art-template x 2,707 ops/sec ±0.12% (96 runs sampled)
tempura x 2,922 ops/sec ±0.31% (96 runs sampled)
```
--------------------------------
### esbuild Bundler Plugin for Tempura
Source: https://context7.com/lukeed/tempura/llms.txt
Shows how to integrate Tempura templates into an esbuild build process. The plugin transforms `.hbs` files into importable JavaScript modules at build time, eliminating runtime parsing overhead. All `tempura.transform()` options are supported.
```javascript
import { build } from 'esbuild';
import tempura from 'tempura/esbuild';
await build({
entryPoints: ['src/index.js'],
bundle: true,
outdir: 'dist',
plugins: [
tempura({
// All tempura.transform() options are supported
format: 'esm',
// Optionally pre-declare global props
props: ['user', 'config'],
})
]
});
// After bundling, .hbs files are importable as render functions:
// src/greeting.hbs:
// {{#expect name}}
//
Hello, {{ name }}!
import greet from './greeting.hbs';
console.log(greet({ name: 'World' })); //=> "
Hello, World!
"
```
--------------------------------
### Define Custom Blocks in Tempura
Source: https://context7.com/lukeed/tempura/llms.txt
Shows how to define and use custom blocks for extending template functionality, including synchronous, asynchronous, and recursive block definitions. Use when needing reusable, stateless helper functions within templates.
```javascript
import { compile } from 'tempura';
import { readFileSync } from 'fs';
// Template cache for the `include` block
const Cache = {};
const blocks = {
// Sync block: renders an HTML