Skip to main content
Out of the box, Narrator understands JavaScript itself: arrays, strings, numbers, Math, JSON, promises, Map and Set, timers and the console. Library calls are read from their names, which is often good enough. A plugin goes further and explains what the library call actually does. Here is a Drizzle query without and with the Drizzle plugin.
Without the plugin
English
With drizzle()
English
Each plugin is its own package, such as @usenarrator/plugin-drizzle. Plugins list @usenarrator/core and @usenarrator/lang-ts as peer dependencies, so every plugin in a project shares one engine. npm and pnpm install them for you. With Yarn, or pnpm with auto-install-peers=false, install them yourself. See What to install.

Available plugins

Validation

zod

Schemas read as the shapes they describe.

Valibot

Schemas, pipes and validation calls.

ArkType

Definitions, including the string syntax.

Data

Drizzle ORM

Queries, operators, relational queries, transactions and schemas.

Prisma

Reads, writes, aggregates, transactions and extensions.

Kysely

Query builder chains, the expression builder and transactions.

SQL

SQL strings and templates from postgres.js, pg, SQLite, Prisma and more.

decimal.js

Arithmetic chains and comparisons read as math.

Servers

Hono

Apps, routes, context, middleware, validation and the RPC client.

Express

Apps, routers, middleware, requests and replies.

Fastify

Routes with schemas, hooks, plugins and decorators.

Elysia

Routes, hooks, lifecycle, TypeBox schemas and Eden.

tRPC

Routers, procedures, middleware and clients.

Frontend

React

Components as the UI they show, hooks, context and actions.

Next.js

Routes from file paths, route handlers, the proxy and caching.

TanStack Query

Queries, mutations and the query client, for v4 and v5.

Payments, auth and AI

Stripe

Billing calls, amounts, pagination and webhook events.

Autumn

Checking and tracking usage, plans, customers, handlers and React hooks.

Better Auth

Auth configuration, plugins and client calls.

AI SDK

Model calls, tools, agents, streaming and the UI hooks.

Background jobs

BullMQ

Queues, job options, schedulers, workers and flows.

Inngest

Functions, triggers, flow control and durable steps.

Trigger.dev

Tasks, schedules, triggering, waits and metadata.

Temporal

Workflows, activities, messages, workers and the client.

Effect and testing

Effect

Generators, pipes, errors, layers, schedules and Schema, for v3 and v4.

Testing

describe, it, expect and matchers from Bun, Jest and Vitest.

Using plugins

Plugins are factory functions. Pass them to the TypeScript source language in the order you want them applied. When two plugins have a rule for the same call, the later one wins.
plugins also accepts arrays of plugins, so a codebase can bundle its own conventions with the libraries it uses and export them as one value. nextjs() uses this to return its own rules together with a React plugin.

Plugins only speak up where they apply

Loading a plugin doesn’t change how unrelated files read. Most plugins check whether the current file imports their library, or belongs to a package whose package.json depends on it, before they claim a call. The few that skip this check, such as zod, decimal.js, Drizzle and Testing, only claim calls whose shape is specific to their library. That means you can load every plugin for a whole monorepo, and Express’s app.get won’t be read as Hono’s in the package that uses Express. The check uses the dependency manifests you pass to createNarrator, and Dependency detection explains how they are found. The CLI and the browser extension go one step further and only load the plugins whose libraries the repository uses.

Plugins for your own code

The most useful plugin is often the one for your own codebase. It can add your domain’s abbreviations to the glossary, mark plumbing parameters like ctx as ambient so they disappear from sentences, name your error classes, and explain in-house helpers. See Writing a plugin.