ποΈβArchitecture
Which package owns what, and why is the seam where it is?
The packages
@getnarro/core the runtime: Presentation, Slide, navigation, motion
@getnarro/shared-ui ~50 slide components, no runtime dependency on core
@getnarro/markdown the markdown/MDX dialect + its Vite plugin
@getnarro/marketplace themes, colour schemes, template metadata
@getnarro/cli new / dev / build / export / import
@getnarro/mcp-server MCP tools and resources for AI assistants
@getnarro/docs these pages as data + the generated API reference
create-narro npm create narro
Why the seams are there
core and shared-ui are separate because they change at different rates
and for different reasons. core owns behaviour β how navigation works, when a
slide is active, how transitions run. shared-ui owns appearance. A deck can
use core alone and hand-write its markup, which is exactly what the minimal
template did until the docs made shared-ui the assumed baseline.
shared-ui has no i18n and no state. Components take text as props. That
keeps them usable from markdown, from React, and from generated code without
each caller having to set up a provider.
markdown does not live in cli. The dialect is a library β the Vite
plugin, the compiler, and the layouts are all importable β so a scaffolded
project can use it without depending on the CLIβs much heavier install
(Playwright, sharp, the Google APIs client).
create-narro does not live in cli either, and cannot: npm create narro
resolves the create-narro package specifically, and scaffolding has to run
before anything is installed. @getnarro/cli depends on it so narro create
and create-narro share one implementation and one copy of the templates.
How a deck renders
Both modes converge on the same runtime.
React mode. Your App.tsx composes Presentation and Slide directly.
Vite builds it like any other React app.
Markdown mode. The @getnarro/markdown Vite plugin compiles deck.md into
virtual modules:
virtual:narro/deck the deck component
virtual:narro/deck.css Tailwind, scanning the deck for utility classes
virtual:narro/slot/<i>/<n> one compiled MDX module per slot
virtual:narro/layout/<name> a resolved layout component
The result is a tree of Presentation and Slide β the same components React
mode uses. This is why the two modes share navigation, transitions, presenter
view, and export: there is only one runtime, and markdown is a front end to it.
Editing the deck recompiles only the slots whose content changed.
Core concepts
A slide is a component. No slide registry, no ordering metadata β order is
source order, and a slide is addressable by id.
Activity is context, not a prop. useSlideActive() tells a component
whether its slide is on screen. This is what lets animations start when the
audience sees them, and lets off-screen backgrounds stop doing work.
Fragments are navigation steps. They participate in the same next/previous sequence as slides, which is why a fragment reveal and a slide advance feel identical to the presenter.
Layouts resolve by name, most specific first. A deckβs own layouts/
directory shadows the theme, which shadows the built-ins. Overriding one layout
never means forking the rest.