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 »
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 | examples/vue3 — build + Playwright (Vue 3 tests) |
| Nuxt | ^4.5.0 | examples/nuxt4 — build + Playwright (Nuxt 4 tests) |
| Svelte | ^5.46.4 | examples/svelte5 — build + Playwright (Svelte 5 tests) |
| SvelteKit* | ^2.53.0 | examples/sveltekit — build + Playwright + svelte-check (SvelteKit tests) |
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.
* 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.
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?".
Supported frameworks
| Framework | Support* | Auto-CodeGen* | Auto-Docs* |
|---|---|---|---|
| Vue → | ✅ | ✅ | 🏗️ |
| Nuxt → | ✅ | ✅ | 🏗️ |
| 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: Generates documentation and controls automatically by analyzing the imported components.
Community
If you have questions or need help, reach out to the community on GitHub Discussions.