Type-safe, composable string templating and formatting for llms.
prmt is a tiny, type-safe library for building composable string templates and formatting. Useful for ai prompts, and anywhere you need to need text templating and/or formatting.
It allows you to write prompts like this:
const result = generateText({
model: myModel,
prompt: format`
// Date is automatically AI-friendly stringified
Today is ${new Date()}.
// This will create a bullet list
Follow these steps:
${steps}
// Won't render boolean false
${shortOutput && '- Only answer with a single sentence.'}
Answer the given query: ${query}
You are now connected to a human.
`
})
- Allows writing comments in prompts
- Cleans up unnecessary whitespace and formats string
- Built-in stringifiers for dates, arrays, booleans, and others
- Built-in transformers for whitespace, comments, and formatting
- Type-safe templates with argument interpolation
- Easily add your own stringifiers and transformers
- Fully typed, zero dependencies
Picks your package manager automatically:
npx nypm install prmt
Or manually:
npm install prmt
Format and clean up multi-line strings with the format
tag:
import { format } from 'prmt';
const guidelines = [
'Be concise',
'Use markdown',
// 'Never use emojis',
];
const prompt = format`
// This is a comment
Adhere to the following guidelines:
${guidelines}
`;
// Output: 'Adhere to the following guidelines:\n- Be concise\n- Use markdown'
- Comments (
// ...
) are stripped - Extra whitespace and newlines are normalized
- Arrays are formatted as bullet lists
- Dates, booleans, objects, and more are stringified sensibly
Note: The logic for comments is currently very simple: It removes everything after //
until the end of the line.
You can create a custom format instance:
import { createFormat } from 'prmt';
const customFormat = createFormat(/* custom config */);
See Custom Stringifiers and Custom Transformers
Create type-safe templates with argument interpolation:
import { template } from 'prmt';
const greeting = template<{ name: string }>`Hello ${'.name'}`;
greeting({ name: 'John' }); // 'Hello John'
You can also use functions:
const birthday = template<{ birthday: Date }>`
You were born ${user => Date.now() - user.birthday.getTime()}ms ago.
`;
birthday({ birthday: new Date('1990-01-01') }); // 'You were born 131558400000ms ago.'
You can create a template with a custom format instance:
import { createTemplate, createFormat } from 'prmt';
const format = createFormat({ /* custom config */ });
const myTemplate = createTemplate({ format });
See Custom Stringifiers and Custom Transformers
Extend prmt's built-in stringifiers. They will be applied in the order they are defined, before any built-in stringifiers.
import { createFormat, stringifier, builtInStringifiers } from 'prmt';
const customFormat = createFormat({
stringifier: {
// replace the built-in date stringifier
date: stringifier({
when: (value) => value instanceof Date,
stringify: (value) => value.toISOString(),
}),
// add a custom stringifier for user objects
user: stringifier({
when: (value): value is User => isUser(value),
stringify: (value) => `User: ${value.name}`,
}),
},
});
customFormat`${new Date('2025-01-01')}`; // '2025-01-01T00:00:00.000Z'
customFormat`${user}`; // 'User: John'
Extend prmt's built-in transformers to customize the final string output. They will be applied in the order they are defined, after any built-in transformers.
import { createFormat } from 'prmt';
const upperFormat = createFormat({
transformers: {
uppercase: (value) => value.toUpperCase()
},
});
upperFormat`
Hello
World
`; // 'HELLO\nWORLD'
prmt
includes a built-in utility to mix and match built-in stringifiers and transformers.
pick
- only keep the given built-insomit
- exclude the given built-insextend
- add or override built-ins
import { createFormat, stringifier } from 'prmt';
const onlyDateFormat = createFormat({
stringifier: builtInStringifiers
.pick('array') // only keep the array stringifier
.extend({
date: stringifier({
when: (value) => value instanceof Date,
stringify: (value) => value.toISOString(),
}),
}),
});
onlyDateFormat`${new Date('2025-01-01')}`; // '2025-01-01T00:00:00.000Z'
Or for transformers:
import { createFormat, builtInTransformers } from 'prmt';
const rawFormat = createFormat({
// keep all built-in transformers, except the one we don't want
transformers: builtInTransformers.omit('removeMoreThan2ConsecutiveNewlines'),
});
rawFormat`
Hello World
`; // '\n Hello World\n'
format
by default returns a string type. You can optionally enable type branding using module augmentation to return a branded string type instead.
This is useful to make sure strings are properly formatted before being used in a prompt.
// prmt.d.ts
import { FormattedString } from 'prmt';
declare module 'prmt' {
interface FormatFn {
(strings: TemplateStringsArray, ...values: unknown[]): FormattedString;
}
}
bun run build
bun test
This project uses semantic-release for automated releases and Conventional Commits for commit messages.