Getting started with Poveste
Overview
poveste is the Romanian word for "story", pronounced
/poˈveste/(po-VES-teh) . Say it however you like — "po-VEST" works too. Coming from histoire? See the migration guide.
Poveste is a tool to generate stories applications (or "books").
Learn more about Poveste here »
Installation
A book is poveste plus the plugin for your framework. There is no single command that is right for all of them, so pick yours below — each guide has the exact packages, the config file they go in, and a first story.
npm i -D poveste @poveste/plugin-<framework>- Vue → —
povesteand@poveste/plugin-vue - Nuxt → — the Vue packages, plus
@poveste/plugin-nuxt - Quasar → — the Vue packages, plus
@poveste/plugin-quasar - Svelte → —
povesteand@poveste/plugin-svelte - SvelteKit → — the same two as Svelte
Try it in a live editor
Supported versions
Each row below is the range Poveste actually declares in peerDependencies, next to the thing that proves it. We deliberately do not advertise versions we cannot test — if a range is wider than the CI job behind it, the range is the bug.
| Supported | Proven by | |
|---|---|---|
| Node | ^22.22.2 || ^24.15.0 || >=26.0.0 | Node floor — installs the tarballs and builds a book on 22.22.2 |
| Vite | ^8.0.0 | every example |
| Vue | ^3.5.26 | Example e2e (vue3) — builds that book and runs Playwright against it |
| Nuxt | ^4.5.0 | Example e2e (nuxt4) — builds that book and runs Playwright against it |
| Svelte | ^5.46.4 | Example e2e (svelte5) — builds that book and runs Playwright against it |
| SvelteKit* | ^2.53.0 | Example e2e (sveltekit) — builds that book and runs Playwright against it |
| Quasar | ^2.24.0 | Example e2e (quasar) — builds that book and runs Playwright against it |
| Quasar App Vite | ^3.8.0 | Example e2e (quasar) — builds that book and runs Playwright against it |
Vite 8 is a hard floor, not a preference: Poveste's own build runs on Rolldown. That is also what sets the Nuxt and Svelte floors — Nuxt only moved to Vite 8 in 4.5.0, and Svelte 4's last compatible @sveltejs/vite-plugin-svelte (v3) caps at Vite 5, so no release pairs Svelte 4 with the Vite we require.
The same chain sets the exact Svelte number. Vite 8 forces @sveltejs/vite-plugin-svelte@^7 — the first major to peer it — and v7 in turn requires svelte@^5.46.4. Svelte 5.0–5.46.3 therefore cannot be assembled into a working Poveste project at all, which is why the range starts where it does rather than at ^5.0.0.
Quasar takes two rows because a Quasar project installs two things: the framework and the build tool that drives it. @poveste/plugin-quasar peers both, and examples/quasar is a conformance book, so one job proves the pair.
* SvelteKit is declared as an optional peer. @poveste/plugin-svelte drives plain Svelte and SvelteKit alike, so a plain-Svelte project has no @sveltejs/kit installed and a required peer would warn on every such install. Optional means the range is enforced when Kit is present and ignored when it is not. See the SvelteKit section.
Node is the one exception to "declared in peerDependencies": it is an engines field on every published package, so npm warns you at install time rather than leaving you to find out at runtime.
The range is not ours to choose freely — it is what jsdom, which Poveste uses to collect stories, imposes on anything that depends on it. Declaring the same range means npm's warning names Poveste rather than a transitive dependency you did not ask for. The floor was >=26 until a run on the minimum showed the requirement was never real: >=26 was what CI happened to run, which proves Poveste works on 26, not that it needs it.
Package managers
CI runs pnpm 11.20.0, so that is the best-tested path. npm is covered too, by a release-gating smoke test that packs the real tarballs, installs them into a throwaway project with npm install — no workspace symlinks — and runs a real poveste build. Yarn is not tested; it is expected to work and reports are welcome.
Bun works from 1.4.0, as both the installer and the runtime — bun install then bun --bun run story:build builds a book. Earlier releases do not, and the reason is the version Bun reports rather than anything Poveste does: process.versions.node is 22.6.0 on 1.2.x and 24.3.0 throughout 1.3.x, and neither satisfies the engines.node above. Below that floor a story build hangs during collection instead of failing — Bun's worker pool never returns, which is oven-sh/bun#3787, open since 2023 against histoire.
bun install does not enforce engines, so nothing warns you. That is why the floor is written here rather than only in the manifest. Bun is not in CI, so like Yarn and macOS it is expected to work rather than vouched for.
Operating systems
Linux is the best-tested path — every workflow runs on ubuntu-latest. Windows is covered by a dedicated windows-latest job that installs, builds, runs the unit tests, and then collects and builds a real book end to end — the story-collection code (the storyMatch globs, the vite-node module graph, path handling throughout) is where a cross-platform bug would surface, so that is what the job exercises. macOS is not in CI; it is the primary development platform and expected to work, but like Yarn above it is not something a workflow vouches for.
Version policy
- One major per framework. We support the latest major of each framework and drop the previous one when keeping it would mean shipping a combination no CI job runs.
- Ranges follow the tests, not the other way round. When a floor rises, the example and its workflow move first; the
peerDependenciesrange follows in the same change. - Floors move in minor releases while Poveste is pre-1.0, and are always called out in the release notes as a breaking change.
- The commit type picks the number. A
featlands a minor, everything else lands a patch — the same field changelogithub groups the release notes by, so the notes and the version can't disagree. - Milestones are targets, not guarantees. A milestone names the release its issues are aimed at. What actually publishes is whatever was ready; the number still comes from the commit types, so the notes and the version cannot disagree.
- Toolchain work is a standing track, not its own milestone.
track:toolchainissues wait in Backlog and move to a version milestone when someone picks one up, rather than being batched into a release of their own. - Majors are declared, not derived. No commit type produces one. Pre-1.0 a breaking change lands in a minor, so nothing in the log will ever add up to a major on its own.
What 1.0 means
1.0 is a promise that the public surface — the config file, the Hst global, <Story> and <Variant> props, the plugin interface and the package names — will not break without a major.
The Stable surface milestone is that promise's checklist. Everything in it either costs a major to fix afterwards, or is something we already advertise and do not yet deliver. When the milestone is empty the 1.0 conversation is open — it does not happen by itself, and the issues in it are the whole answer to "what is 1.0 waiting for?".
When a component throws
A story whose component throws shows an error over the preview, with the message and stack, and the variant and story are marked in the lists beside it.
Two limits are worth knowing, because neither is obvious from a green run:
poveste builddoes not render your components. Collection runs in Node and evaluates the story file; the component itself only renders in a browser. So a book where every variant throws still builds, and still exits0. A CI job that runspoveste buildas a gate is checking that stories collect, not that they work.- A story is only marked once it has rendered. Variants mount as they come into view, so an unopened story carries no marker. The absence of a marker means "not seen to fail", never "fine".
Supported frameworks
| Framework | Support* | Auto-CodeGen* | Auto-Docs* |
|---|---|---|---|
| Vue → | ✅ | ✅ | - |
| Nuxt → | ✅ | ✅ | - |
| Quasar → | ✅ | ✅ | - |
| Svelte → | ✅ | - | - |
| SvelteKit → | ✅ | - | - |
| Solid | - | - | - |
| Angular | - | - | - |
| React | - (Alternative) | - | - |
*Support means the following is available:
- Collect and render stories
- Render controls pane content with state sync
- Builtin controls wrappers
- Static source
*Auto-CodeGen: Generates copiable source code dynamically from the current story state. Generally requires a Virtual DOM.
*Auto-Docs: Generating documentation and controls by analysing the imported components. Not implemented, for any framework. It is on the roadmap rather than in progress — the approach is still an open question (#159), so this column reads - everywhere until something exists behind it.
Community
If you have questions or need help, reach out to the community on GitHub Discussions.