This document covers the JavaScript/TypeScript implementation of Dotprompt, located in the js/ directory. This implementation serves as the reference implementation for the Dotprompt specification and provides a Node.js/browser-compatible library for parsing, compiling, and rendering executable prompt templates.
For information about the language-neutral Dotprompt specification, see Core Concepts. For implementations in other languages, see Python Implementation, Go Implementation, and Java Implementation.
The JavaScript implementation is published as the dotprompt npm package at version 1.1.2. It provides a TypeScript-first API that compiles to both ESM and CommonJS formats.
Sources: js/package.json1-52
The implementation has minimal production dependencies:
| Dependency | Version | Purpose |
|---|---|---|
handlebars | ^4.7.8 | Template engine for rendering prompts |
yaml | ^2.8.2 | YAML frontmatter parsing |
Development dependencies include TypeScript 5.9.3, Vitest for testing, and tsup for bundling.
Sources: js/package.json41-44 js/package.json29-39
The package uses a dual-mode build process:
The build script invokes two tools:
tsup-node compiles source files into dual-format JavaScript bundlestsc validates types without emitting outputSources: js/package.json13-15
Sources: js/src/dotprompt.ts1-533 js/package.json5-6
The Dotprompt class is the main entry point for the library, providing methods for parsing, compiling, and rendering prompt templates.
Sources: js/src/dotprompt.ts68-92
The constructor accepts an options object with the following structure:
Each resolver function provides dynamic lookup capability for their respective resource types. Static registrations via the record properties take precedence over resolver lookups.
Sources: js/src/dotprompt.ts44-63
The Dotprompt class provides three registration methods for extending functionality:
defineHelper(name: string, fn: Handlebars.HelperDelegate) - Registers a custom Handlebars helper function and adds it to the knownHelpers registry for optimized compilation.
definePartial(name: string, source: string) - Registers a named partial template that can be referenced via {{>partialName}} syntax.
defineTool(def: ToolDefinition) - Registers a tool definition in the internal tools map, making it available for resolution during metadata processing.
All registration methods return this for method chaining.
Sources: js/src/dotprompt.ts101-128
Sources: js/src/dotprompt.ts136-140 js/src/dotprompt.ts169-232
The renderMetadata method processes prompt metadata through several resolution stages:
Tool resolution uses a fallback chain: registered tools → tool resolver → unregistered (left as string names). Schema conversion happens concurrently for input and output schemas.
Sources: js/src/dotprompt.ts274-306 js/src/dotprompt.ts381-421 js/src/dotprompt.ts314-355
The resolvePartials method identifies and loads partial templates before compilation:
The system uses the Handlebars AST visitor pattern to statically analyze templates for partial references, then loads them dynamically before template compilation.
Sources: js/src/dotprompt.ts429-453 js/src/dotprompt.ts461-491
The parse.ts module handles extraction of YAML frontmatter and conversion of rendered templates into structured message arrays.
The parseDocument function is the primary entry point, returning a ParsedPrompt object that combines the template body with parsed metadata.
Sources: js/src/parse.ts (file reference, specific line numbers not provided in context)
The toMessages function transforms a rendered template string containing marker syntax into a structured array of Message objects:
Sources: js/src/parse.ts (cited by dotprompt.ts:224)
Within each message segment, the parser recognizes several special marker patterns:
| Marker Pattern | Part Type | Description |
|---|---|---|
<<<dotprompt:section X>>> | Text | Section boundaries in content |
<<<dotprompt:media:url URL [TYPE]>>> | Media | Embedded media references |
| Plain text | Text | Standard text content |
The parsing logic extracts these markers and constructs typed Part objects that conform to the GenAI message format.
Sources: js/src/parse.ts (referenced by helpers and message construction logic)
The helpers.ts module provides seven standard Handlebars helpers that extend templating capabilities for GenAI use cases.
Sources: js/src/helpers.ts1-69
All marker-emitting helpers return SafeString instances to prevent HTML escaping:
json(serializable, options) - Serializes JavaScript values to JSON. The indent hash parameter controls formatting (0 for compact, >0 for pretty-printed).
role(role) - Emits a role boundary marker. The template processing pipeline later splits the rendered output on these markers to create separate messages.
history() - Emits a history insertion marker. During message generation, the data.messages array is inserted at this location.
section(name) - Emits a section boundary marker. Used for organizing content within a single message.
media(options) - Constructs a media reference marker from url and optional contentType hash parameters. The parser converts these into Media part objects.
ifEquals(arg1, arg2, options) / unlessEquals(arg1, arg2, options) - Conditional block helpers that use strict equality (===) comparison. They invoke options.fn(this) for the truthy case and options.inverse(this) for the falsy case.
Sources: js/src/helpers.ts23-68
The Dotprompt class registers all built-in helpers during construction through the registerInitialHelpers method:
The knownHelpers registry enables Handlebars compilation optimization by pre-declaring all available helpers.
Sources: js/src/dotprompt.ts90-91 js/src/dotprompt.ts497-517
The picoschema.ts module converts the simplified Picoschema format into standard JSON Schema.
Sources: js/src/picoschema.ts (referenced by dotprompt.ts:322-324)
The parser maps Picoschema primitive types to JSON Schema types:
| Picoschema | JSON Schema | Notes |
|---|---|---|
string | "string" | Basic string type |
number | "number" | Numeric values |
boolean | "boolean" | True/false values |
integer | "integer" | Whole numbers |
object | "object" | Generic object |
any | {} | No type constraint |
Optional fields are indicated with ? suffix (e.g., age?: number), which excludes the field from the required array.
Sources: js/src/picoschema.ts (type mapping logic)
When the parser encounters a $SchemaName reference, it invokes the schemaResolver callback:
The wrappedSchemaResolver method in the Dotprompt class implements this lookup, checking the local schemas registry before delegating to the user-provided schemaResolver.
Sources: js/src/dotprompt.ts363-373 js/src/picoschema.ts
The JavaScript implementation provides comprehensive TypeScript type definitions for all public APIs.
Sources: js/src/types.ts (referenced by dotprompt.ts:23-35)
The library defines three resolver function types for dynamic resource lookup:
All resolvers support both synchronous and asynchronous implementations, returning null when a resource is not found.
Sources: js/src/dotprompt.ts39-41 js/src/types.ts
The Dotprompt class and its methods use two generic type parameters for type safety:
Variables - Constrains the shape of input data passed to templatesModelConfig - Constrains the shape of model-specific configuration objectsThese generics flow through the type system:
parse<ModelConfig>() → ParsedPrompt<ModelConfig>
compile<Variables, ModelConfig>() → PromptFunction<ModelConfig>
render<Variables, ModelConfig>() → RenderedPrompt<ModelConfig>
Sources: js/src/dotprompt.ts136-157
The JavaScript implementation uses Vitest for testing, with a specialized system for executing cross-language specification tests.
Sources: js/spec.test.ts (referenced by package.json:17)
Each YAML spec file defines test suites with the following schema:
The test generator dynamically creates Vitest describe() and it() blocks for each suite and test case.
Sources: spec/*.yaml (referenced in high-level diagrams)
The test framework instantiates a new Dotprompt instance for each test suite, registers any specified helpers and partials, compiles the template, executes it with test data, and compares the result against expected output.
Sources: js/spec.test.ts (test execution logic)
Test coverage is measured using @vitest/coverage-v8:
The coverage report tracks:
Sources: js/package.json17 js/package.json32
The JavaScript implementation provides a complete, TypeScript-first implementation of the Dotprompt specification. Key architectural decisions include:
Dotprompt instance creates its own Handlebars runtime via noConflict(), preventing global state pollutionThe implementation serves as the reference for other language ports and maintains version 1.1.2 with stable APIs.
Sources: js/src/dotprompt.ts1-533 js/package.json1-52 js/src/types.ts js/src/parse.ts js/src/helpers.ts1-69 js/src/picoschema.ts
Refresh this wiki
This wiki was recently refreshed. Please wait 5 days to refresh again.