Writing prompts in natural language is great—until they become messy with multiple steps, output format descriptions, and too many lines of text...
With prai, prompts become code—structured, maintainable, and debuggable—leading to high-quality, reliable outputs.
npm install prai
Let's look at some prai use cases.
Desinging a Homepage | ![]() |
---|---|
Creating a Presentation | ![]() |
Creating a Database Schema | ![]() |
We recommend prai for problems that are best solved with a structured process, where some steps involve reasoning or decision-making.
import { History, Model, openai, step } from 'prai'
import { z } from 'zod'
// 1. Inputs for our theme generation process
const brandName = `pmndrs`
const brandDescription = `Open source developer collective`
// 2. Zod schema for a color in hsl - will be given to the LLM as the expected output format
const colorScheme = z
.object({
hue: z.number().describe('in degree (0-360)'),
saturation: z.number().describe('in percent (0-100)'),
lightness: z.number().describe('in percent (0-100)'),
})
.describe('hsl color')
// 3. Create a model based on an AI provider (openai, groq, more support comming soon)
const model = new Model({ name: 'gpt-4.1-mini', apiKey: 'insert key here', provider: openai({ apiKey: "" }) })
// 4. create a chat history
const history = new History()
// 5. First step
const adjectives = await step(
//6. Enforce a strict schema on the output (a list of strings) - LLM will be forced to comply
`list some adjectives fitting the design of the ${brandName} brand which is a ${brandDescription}`,
z.array(z.string()),
{ model, history }
)
// 7. Second step—generate a basic theme
const coreTheme = await step(
// 9. We can reference results from history using history.reference
`Based on the ${history.reference(adjectives)}, derive fitting color theme`,
z.object({
background: colorScheme,
foreground: colorScheme,
primary: colorScheme,
secondary: colorScheme,
accent: colorScheme,
border: colorScheme,
radius: z.number().describe('radius in rem'),
}),
{ model, history }
)
// 10. Final step—expand into a full shadcn theme
const result = await step(
`Expand the ${history.reference(coreTheme)} to a full shadcn theme`,
z.object({
background: colorScheme,
//Full scheme in /examples/theme
}),
{ model, history }
)
console.log(result.value)
- prai-trace?
- Metrics (prometheus integration for metrics)
- prebuild image & audio embeddings for reuse?
- RAG step?
- toolStep (support tool calls to build agent steps; make sure we can do a multi-step with a tool call and then e.g. a json result for e.g. returning specific data from a general search)