v0.1 · MIT · 2KB · zero deps

Catch prompt typos
before they reach the model.

tprompt is a 2KB TypeScript primitive that turns {{usrName}} into a tsc error — not a silent runtime string the model receives.

$ pnpm add @nkwib/tprompt

One primitive

prompt('...{{name}}...'). That's it. Variables are inferred at the type level from the literal string — no decorators, no codegen, no runtime schema.

Typo-proof

{{usrName}} in the template + userName at the call site = compile error. Your prompt cannot ship with an unbound placeholder.

2KB. Zero deps.

sideEffects: false, ESM source, dual-published. Validation is structural — bring Zod, Valibot, ArkType, or your own.

Pluggable delimiter

Default is {{var}} (LangChain / BAML / OpenAI prompts). Single-brace via tprompt/single-brace. Custom via makePromptTag.

Multi-turn ready

.partial({role}) binds a subset; the rest is supplied later. Partials don't compose — by design — so the type stays honest.

Optional runtime check

.validate(schema) throws; .validateSafe(schema) returns a Result. Two modes, no overlap. Pick one per call site.

Drop-in for the prompt ecosystem

Default {{var}} matches LangChain, BAML, the OpenAI prompt cookbook, and Anthropic's prompt library. Coming from f-string territory? One subpath import switches to {var}.

Delimiter guide
// Default: {{var}}
import { prompt } from '@nkwib/tprompt';
prompt('Hi {{name}}');

// Single-brace: {var}
import { prompt } from '@nkwib/tprompt/single-brace';
prompt('Hi {name}');

// Bring your own:
import { makePromptTag } from '@nkwib/tprompt';
const angle = makePromptTag({ open: '<<', close: '>>' });

The whole library is one idea.

Variables only. No template logic. No DSL. No surprises.

tprompt Type-safe prompt templates for TypeScript