# Narro > Developer-first presentations. Author decks in Markdown or React, render them > in the browser, export to PPTX, PDF, or a single HTML file. Narro is text, so you can write a deck directly. This file plus the linked resources are enough — you do not need to have seen the repository. ## Read this first - **Everything in ONE file (no follow-up fetches — take this if you can only fetch once):** https://getnarro.com/llms-full.txt - **No web access?** The same documentation ships through npm, over the registry that already installed your packages: `npm i -D @getnarro/docs`, then read `@getnarro/docs/llms-full.txt`, `@getnarro/docs/catalog.json`, or `@getnarro/docs/content/.md`. It pins to the version actually installed. - **Rules to paste into your own AGENTS.md / CLAUDE.md / .cursor/rules:** https://getnarro.com/docs/agent-rules.md - **Then check your work** — this is the part that matters more than the prose: npx @getnarro/cli check deck.md --render # what every slide renders: elements, classes, text npx @getnarro/cli check deck.md --strict # the CI gate: warnings are errors npx @getnarro/cli check deck.md --fit # does the content fit the slide? (needs a browser) npx @getnarro/cli build deck.md # the real build `check` names the bad layout, the unknown theme, the malformed directive, and every class that was written but landed on nothing. A deck you have not run it on is a deck you have not verified. `--strict` is the CI gate; `--render` answers "did that class attach to the word or the paragraph?" without a browser; `--fit` is the only check that can tell you a dense slide is clipping, and the only narro-provided check React mode has (point it at `dist/`). ## Fastest path to a deck npx @getnarro/cli new deck.md # a single-file markdown deck npx @getnarro/cli dev deck.md # open it, hot-reloading Or scaffold a React project: npm create narro@latest my-deck Note: the npm package named `narro` is unrelated to this project. Narro's packages are all under the `@getnarro/` scope, and the CLI binary `narro` comes from `@getnarro/cli`. ## Which mode | You want | Use | Start at | | --- | --- | --- | | One file, no build setup, deck is prose-shaped | Markdown mode | https://getnarro.com/docs/markdown-mode.md | | Live components, data, custom interaction | React mode | https://getnarro.com/docs/react-api.md | You do not have to choose permanently: markdown decks climb to per-element Tailwind, then to ejected React layouts, then to MDX, without being rewritten. ## Closed sets — do not invent names Every value below is generated from the shipping source. If a name is not in this list it does not exist, and a deck naming it will build and render wrong rather than fail loudly. The full machine-readable set, including every component's props and every exported string union, is one fetch: - https://getnarro.com/catalog.json - https://getnarro.com/components.json — every component's props, read out of the TypeScript types - https://getnarro.com/llms/.md — one component's reference, on its own URL (names are case-sensitive and exact: https://getnarro.com/llms/Presentation.md). https://getnarro.com/llms/index.md lists every valid name; a guessed name 404s, so look it up rather than retrying. - https://getnarro.com/schema/deck-frontmatter.schema.json - https://getnarro.com/schema/slide-frontmatter.schema.json Built-in layouts (`layout:` in slide frontmatter): default, cover, section, quote, end, two-column, three-column, image-right, image-full Themes (`theme:` in deck frontmatter): default, corporate-dark, minimalist-light, creative-gradient, ocean-blue, forest-green, sunset-warm, midnight-purple, tech-dark, startup-bold, academic-classic Colour schemes — **not a frontmatter key.** They are palettes, applied with `narro themes apply --color-scheme` or read as data from `@getnarro/marketplace` (`getColorSchemeById`): ocean-blue, sunset-warm, forest-mist, royal-purple, rose-gold, arctic-blue, charcoal-slate, emerald-night Font presets — **not a frontmatter key.** Applied from React with `applyFontPreset(name)` from `@getnarro/core`: system, inter, roboto, openSans, lato, montserrat, poppins, raleway, sourceSerif, playfairDisplay, merriweather, jetBrainsMono Deck frontmatter keys: title, author, date, theme, template, aspectRatio, transition, class, keyboard, mouse, touch, routing, favicon, maxDuration, plus any key beginning `x-` — those are yours, nothing reads them, and `check --strict` stays quiet. Slide frontmatter keys: layout, class, id, transition, background, notes Tailwind in `{ … }`: whatever Tailwind calls it, including arbitrary values (`text-[10px]`, `bg-[#0a0a0a]`), opacity modifiers and fractions (`bg-white/5`, `w-1/2`), variants (`hover:`, `md:`, `dark:`), half-steps (`p-1.5`) and `!` overrides. The one exception is a literal `{` or `}` inside the block — put that class in `deck.css`. Templates for `npm create narro@latest`: markdown-minimal, markdown-app, markdown-docs, minimal, corporate, developer, creative, bold-statement, visual-story, data-narrative, startup-pitch, tech-conference, template0 Components (80 total; props at https://getnarro.com/components.json): AnimatePresence, Canvas, CanvasElement, CanvasShape, ErrorBoundary, ErrorOverlay, MarqueeRow, MasonryBackground, Motion, MotionContainer, MotionList, MotionNumber, MotionPresence, MotionSpotlight, MotionStep, MotionSteps, MotionText, MotionTransform, NebulaBackground, Notes, OverviewGrid, Presentation, PresenterNotes, Slide, SlideContent, TransformSlide, TrustedByMarquee, AgendaItem, AnimatedList, Animation, Badge, BigText, Callout, Card, Chart, Code, CommentForm, CommentItem, CommentMarker, CommentPanel, ContentSlide, CountingNumber, Diagram, DottedArc, DualColumnTextAndImage, Embed, FlowDiagram, FourColumn, Fragment, Grid, Heading, HexPatternBackground, Icon, Image, ImageBackground, ImageSlide, ImageSpotlight, InfoCardWithIcon, List, LogoGrid, MorphElement, ProcessFlowChart, ProfileCard, ProgressRing, Quote, ScrollableImage, Text, ThreeColumn, TimelineWithIndicators, TitleSlide, TitleSlideWithElement, TwoColumn, TwoColumnHighlight, TypewriterText, Video, WaveLine, WordReveal, Workflow, WorkflowStep, ZoomImage ## Documentation Every page below is also available as markdown by appending `.md` to its URL — same content, a fraction of the tokens, no markup to parse back out. ### Start here - [Introduction](https://getnarro.com/docs/introduction.md): What is Narro, and should I be writing markdown or React? - [Installation](https://getnarro.com/docs/installation.md): What do I install, and what does the project look like afterwards? - [First Deck](https://getnarro.com/docs/first-deck.md): What does a working React deck look like, end to end? - [Markdown Mode](https://getnarro.com/docs/markdown-mode.md): How do I split a slide, style one word, or reveal a line — without leaving the markdown file? - [Writing AI Prompts](https://getnarro.com/docs/ai-prompts.md): What do I tell an AI so the deck it writes actually builds? - [Rules for AI Agents](https://getnarro.com/docs/agent-rules.md): What do I paste into my repo so an agent stops writing decks that build wrong? ### Reference - [React API](https://getnarro.com/docs/react-api.md): Which component or hook do I import, and what does it take? - [CLI](https://getnarro.com/docs/cli.md): Which command do I run, and what are its flags? - [Markdown API](https://getnarro.com/docs/markdown-api.md): How do I read, edit, or validate a deck file from my own code instead of by hand? - [Component Reference](https://getnarro.com/docs/components.md): What props does this component take, and which package do I import it from? ### Guides - [Animation](https://getnarro.com/docs/animation.md): How do I reveal a list one line at a time, or move between slides with something other than a cut? - [Navigation](https://getnarro.com/docs/navigation.md): How does the audience move through the deck, and how do I present it? - [Canvas & Positioning](https://getnarro.com/docs/canvas-positioning.md): How do I put something at an exact position instead of in the flow? - [Images & Media](https://getnarro.com/docs/media.md): How do I use an image as a background, tint it, or embed a video? - [Architecture](https://getnarro.com/docs/architecture.md): Which package owns what, and why is the seam where it is? - [Transform Mode](https://getnarro.com/docs/transform-mode.md): How do I zoom and pan across one big canvas instead of cutting between slides? - [Import & Export](https://getnarro.com/docs/import-export.md): How do I get this deck out as PPTX, PDF, or one file I can email? - [AI Integration](https://getnarro.com/docs/ai-integration.md): How do I wire an AI assistant up to Narro so it can write and build decks? - [Theming](https://getnarro.com/docs/theming.md): How do I change the colours, fonts, and overall look of a deck? - [Deck Templates](https://getnarro.com/docs/deck-templates.md): How do I define one house style with named layouts my slides can reference, like a PowerPoint master? - [Troubleshooting](https://getnarro.com/docs/troubleshooting.md): Something is wrong with my deck. What is it, and how do I fix it? - [Limitations](https://getnarro.com/docs/limitations.md): What can't Narro do, and what do I do instead? --- Everything above is https://getnarro.com/llms.txt. Below is every documentation page in full, in reading order. Component props in the API reference are generated from the TypeScript source, so they describe the shipping API rather than a hand-maintained copy of it. --- # Animation > Fragments, transitions, and the motion primitives > > Read this when: How do I reveal a list one line at a time, or move between slides with something other than a cut? ## Fragments A fragment reveals part of a slide on the next keypress instead of showing everything at once. ```tsx import { Fragment } from "@getnarro/shared-ui"; Progressive reveal Appears first Appears second, sliding up Then this ; ``` `Fragment` comes from `@getnarro/shared-ui`, not `@getnarro/core`. | Prop | Type | Default | | --- | --- | --- | | `order` | `number` | source order | | `effect` | `FragmentEffect` | `"fade-in"` | | `duration` | `number` (ms) | — | | `staggerDelay` | `number` (ms) | — | | `isActive` | `boolean` | inherited from the slide | `FragmentEffect` is "fade-in" | "fade-out" | "slide-up" | "slide-down" | "slide-left" | "slide-right" | "scale-in" | "scale-out" | "blur-in". Fragments consume a navigation step: on a slide with three fragments, the first three presses reveal them and the fourth advances. Every key that advances a slide advances a fragment too, including the `PageDown` a presenter's clicker sends. Without an explicit `order`, fragments reveal in source order. Set `order` when you want a different one — two fragments sharing an order reveal together. `trigger="time"` opts out: those fragments reveal on slide entry, staggered by `staggerDelay`, and do not consume a press. ```tsx revealed first then this already there when the slide opens ``` Used outside a `Slide` — a component in a storybook, a page that is not a deck — there is nothing to step, so a fragment reveals on mount. In markdown mode the equivalent is `{.step}`, and it behaves the same way: ```markdown - appears first {.step} - appears second {.step delay=200} ``` ## Slide transitions ```tsx ``` `"none" | "fade" | "slide" | "zoom"`. In markdown, set `transition:` in slide frontmatter, or on the deck to change the default for every slide. ## Motion primitives `@getnarro/core` wraps Framer Motion in components that already know whether their slide is on screen — animations start when the slide appears, not when the deck mounts. ```tsx import { Motion, MotionNumber, MotionText } from "@getnarro/core"; Animated in One word at a time ``` Durations and delays on motion components are in **seconds** (Framer Motion's convention), while `Fragment`'s `duration` is in milliseconds. `MotionEffect` is "fadeIn" | "fadeOut" | "slideUp" | "slideDown" | "slideLeft" | "slideRight" | "scaleUp" | "scaleDown" | "rotateIn" | "flip" | "bounce" | "elastic" | "blur" | "glow" | "typewriter" | "spotlight" | "parallax" | "morphPath" | "stagger" | "wave". See the [component reference](/docs/components) for the full set — `Motion`, `MotionContainer`, `MotionList`, `MotionText`, `MotionNumber`, `MotionPresence`, `MotionSpotlight`, `MotionSteps`, `MotionStep`, `MotionTransform`. ## Gating your own animation To drive animation yourself, ask whether the slide is active. Both packages export the hook — `@getnarro/shared-ui` and `@getnarro/core` — and both read the context `Slide` provides, so either import works: ```tsx import { useSlideActive } from "@getnarro/shared-ui"; function Chart() { const isActive = useSlideActive(); return ; } ``` Without this, every animation on every slide fires on load and is finished before the audience sees it. ## Respecting reduced motion Motion components honour `prefers-reduced-motion`. If you hand-roll animation, gate it the same way: ```css @media (prefers-reduced-motion: reduce) { .animate-draw { animation: none; } } ``` --- # Navigation > Keyboard, mouse, touch, URL routing, overview mode, and the presenter view > > Read this when: How does the audience move through the deck, and how do I present it? ## Keyboard | Key | Action | | --- | --- | | `→`, `Space`, `Page Down` | Next slide or fragment | | `←`, `Page Up` | Previous slide or fragment | | `Home` | First slide | | `End` | Last slide | | `F` | Toggle fullscreen | | `O` | Toggle overview grid | Disable with ``, or `keyboard: false` in deck frontmatter. Worth doing when a slide embeds something that wants the arrow keys itself. ## Mouse and touch Clicking the left or right edge of the deck moves a slide. On touch devices, swipe left and right. Both are controlled by the `mouse` and `touch` props. ## URL routing With `routing` enabled (the default), the URL tracks the current slide: ``` https://example.com/#/slide/intro ← a slide with id="intro" https://example.com/#/slide/3 ← the fourth slide, if it has no id ``` Links stay stable across edits when slides have explicit `id`s — without one, a slide's URL is its index, and inserting a slide earlier changes it. ## Overview mode `O` shows every slide as a grid. Arrow keys move the focus, `Enter` jumps. Useful mid-talk when a question sends you backwards. ## Presenter view `narro dev` serves a presenter view on a second port with the current slide, the next slide, speaker notes, and a timer. Set `maxDuration` (minutes) on the deck to get a countdown: ```tsx ``` The two views stay in sync in both directions, so advancing on either moves both. ## Driving navigation yourself ```tsx import { useNavigation } from "@getnarro/core"; function Agenda() { const { goToSlideById } = useNavigation(); return ( ); } ``` See the [React API](/docs/react-api) for everything `useNavigation` returns. --- # Canvas & Positioning > Place elements at exact coordinates with Canvas, CanvasElement, and CanvasShape > > Read this when: How do I put something at an exact position instead of in the flow? Most slides should use normal flow layout. `Canvas` is for the ones that should not — diagrams, annotated screenshots, anything where an element belongs at a specific point. ## Canvas ```tsx import { Canvas, CanvasElement, CanvasShape } from "@getnarro/core"; {/* positioned children */} ; ``` ## CanvasElement Positions any content. `x` and `y` are percentages of the slide by default, so a deck keeps its layout at every resolution. ```tsx
Top left area
Rotated, semi-transparent ``` Pass a string with a unit (`"100px"`) to position in pixels instead. ## CanvasShape Ten built-in shapes, drawn as SVG so they stay crisp at any scale: `circle`, `rectangle`, `triangle`, `star`, `hexagon`, `pentagon`, `arrow`, `diamond`, `ellipse`, `cloud` ```tsx ``` ## When not to use it Absolute positioning does not reflow. A canvas slide that looks right at 16:9 can overlap at 4:3, and text inside one will not wrap into a new line as it grows. For anything that is fundamentally a list, a comparison, or a body of text, use `SlideContent` and a layout component — they adapt, and they will still look right on a projector you have not seen. Exact prop tables are in the [component reference](/docs/components). --- # Images & Media > Filters, overlays, backgrounds, video, and embeds > > Read this when: How do I use an image as a background, tint it, or embed a video? ## Image filters `Image` applies CSS filters directly, so a photo can be tuned to a deck's palette without an editor in the loop. ```tsx import { Image } from "@getnarro/shared-ui"; The team; ``` Presets: `none`, `blur`, `grayscale`, `sepia`, `brightness`, `contrast`, `saturate`, `hue-rotate`, `invert`, `opacity`, `drop-shadow`. Anything else, pass CSS directly: ```tsx Tuned ``` ## Colour overlays Tint an image to match the deck: ```tsx Tinted ``` Overlays are also the practical way to get readable text over a photo — a dark overlay at 0.5 will rescue almost any background. ## Full-bleed backgrounds ```tsx import { ImageBackground } from "@getnarro/shared-ui"; Over the image ; ``` ## Large and zoomable images - `ScrollableImage` — a tall screenshot the audience scrolls through - `ZoomImage` — click to magnify, for dense diagrams - `ImageSpotlight` — Keynote-style Magic Move between framings of one image across slides, by giving each a shared `spotlightId` ## Video ```tsx import { Video } from "@getnarro/shared-ui";