Narra TypeScript SDK

Living narratives, typed for production.

Narra is the boundary between probabilistic generation and deterministic game systems. It creates quests, dialogue, decisions, and world events as schema-validated data—never executable game logic.

Runtime

Node.js 20+

Modules

ESM + CommonJS

Package

naraworks

Important: Your authoritative game server decides what executes. Narra only returns validated, developer-authorized narrative data.
01

Installation

Install Narra on a trusted Node.js backend. Provider keys must never ship in Unity, Godot, Unreal, or browser clients.

npm install naraworks
// ESM
import { Narra } from "naraworks";
// CommonJS
const { Narra } = require("naraworks");
02

Quick start

Generate a bounded quest from current player and world state.

import "dotenv/config";
import { Narra } from "naraworks";

const narra = new Narra({
  apiKey: process.env.OPENAI_API_KEY!,
});

const quest = await narra.quests.generate({
  player: {
    id: "player_123",
    level: 8,
    reputation: { ashguard: 40 },
  },
  worldState: {
    location: "Ashen Port",
    weather: "storm",
    activeConflict: "merchant_war",
  },
  difficulty: "medium",
  constraints: {
    maxObjectives: 4,
    allowedQuestTypes: ["exploration", "combat", "social"],
  },
});

console.log(quest.title, quest.objectives);
03

Generation architecture

Every provider-backed operation follows the same controlled lifecycle.

01

Context

Player, world, lore, and memory

02

Provider

Structured JSON generation

03

Schema

Strict Zod parsing

04

Guardrails

Limits and action authorization

05

Result

Typed game-safe data

Game stateNarra runtimeValidated output
04

Configuration

import type { NarraConfig } from "naraworks";

const config: NarraConfig = {
  provider: "openai",
  apiKey: process.env.OPENAI_API_KEY,
  model: "gpt-5-mini",
  timeoutMs: 30_000,
  maxRetries: 2,
  database: false,
  defaultSystemPrompt: "Respect established lore and game rules.",
  metadata: { environment: "production" },
  logger: myLogger,
};
provideropenai | xai | gemini | claude | AIProvider
modelProvider-specific default
timeoutMs30000
maxRetries2
databasefalse | Neon configuration
defaultSystemPromptOptional shared narrative rules
05

Providers

Switch providers without changing domain APIs, or implement the shared AIProvider contract for gateways and self-hosted models.

ProviderIDEnvironment key
OpenAIopenaiOPENAI_API_KEY
xAIxaiXAI_API_KEY
Google GeminigeminiGEMINI_API_KEY
Anthropic ClaudeclaudeANTHROPIC_API_KEY
06

Narrative APIs

quests.generate()

Create bounded quests with objectives, hooks, rewards, and constraints.

narrative.generate()

Produce adaptive story beats grounded in current context.

dialogue.generate()

Generate NPC dialogue with tone, relationship, and lore context.

npc.decide()

Return an authorized NPC decision from explicit allowedActions.

world.generateEvent()

Create game-safe world events from simulation state.

players.analyze()

Analyze player patterns for narrative adaptation.

memory()

Store and retrieve durable narrative context.

sessions()

Maintain scoped narrative continuity across play sessions.

07

Memory, lore, and sessions

Ground generation in what already happened. Keep player-specific memory separate from canonical lore and scope continuity to explicit sessions.

Memory

Player choices, relationships, discoveries, and prior outcomes.

Lore

Canonical places, factions, characters, rules, and immutable facts.

Sessions

A bounded timeline for conversation and narrative continuity.

08

Deterministic guardrails

Raw model output is never a trusted game API. Narra validates response shape and enforces developer-defined limits before returning data.

Schema

Malformed JSON rejected

Actions

Unsupported actions rejected

Limits

Objective and item caps enforced

Errors

Typed failures for recovery

09

Neon PostgreSQL persistence

Start with zero-configuration in-memory services. When durable memory is needed, opt into Neon or supply a custom MemoryStore.

const narra = new Narra({
  apiKey: process.env.OPENAI_API_KEY!,
  database: {
    connectionString: process.env.DATABASE_URL!,
  },
});
10

Game-engine integration

Game clients call your trusted backend over authenticated HTTPS. The backend owns Narra, provider credentials, validation, persistence, and final authorization.

Unity
Godot
Unreal
Web
11

Errors, retries, and cancellation

ConfigurationError

Invalid client or provider configuration

ResponseError

Invalid JSON or response shape

GuardrailError

Output violated developer constraints

AuthenticationError

Provider rejected credentials

RateLimitError

Rate limiting survived retries

TimeoutError

Request exceeded timeoutMs

Transient network, 408, 429, and 5xx failures use bounded exponential retries. Provider-backed operations accept an AbortSignal for cancellation.

12

Security model

Trusted server only

Narra client construction, provider keys, private player context, generation calls, persistence, and action authorization.

Game client

Authenticated requests and presentation of server-approved narrative results. Never provider credentials or direct model execution.

Treat player text as untrusted input, minimize context sent to providers, keep secrets out of logs, and authorize every state-changing operation independently of generated output.