Every option’s name, type and default is on the API page.
maxDepth
maxDepth bounds how far into a top-level binding the plugin looks for stores. A property, an index, a Map key and a step into a store’s value each count as one step. Ten steps by default, which is deeper than state is usually nested. A store past that number is not drawn under the binding.
It takes a whole number of 1 or more, or Infinity to walk a binding as deep as it goes. Anything else is refused with a warning. This is not maxValueDepth: that one caps how much of one value a row carries, while this one decides which stores are found at all.
adoptFactories
What adoption reaches, and the two settings this option takes, are in the bundler plugin.
storeTypes
storeTypes gives an adopted store its kind, the word in square brackets. It maps a package name to that package’s store-making exports, and each export to the kind it returns:
nanostoresDevtools({
storeTypes: {
"my-stores": { createCounter: "atom", createSettings: "map" },
},
});
We ship entries for the packages on the Smart Stores list in the nanostores README, so persistentAtom reads as an atom and persistentMap as a map. Your entries are laid over ours per package and per export, so correcting one export changes nothing else. A kind is one of atom, map, deepMap, computed, batched or unknown.
It does not find stores. Adoption does that, so a package with no entry still reaches the tree, only without a kind. It reads the export name, not the local one, so import { persistentAtom as stored } still works. An entry we cannot read is dropped with one warning, and the rest still apply.
fileKey
fileKey rewrites the path shown as a store’s home, and changes nothing but what is displayed. Write a fixed rule, such as fileKey: (path) => path.replace(/^src\/stores\//, ""), so every page load gives the same keys.
Two files mapped to one home keep both sets of stores. Where both hold a $counter, both keys say which file they came from: $counter [store] (a.ts) next to $counter [store] (b.ts).
projectRoot
projectRoot is a Vite option. A file outside the Vite root, such as a linked package in a monorepo, is shown relative to it, so a linked package reads as packages/…. It defaults to Vite’s own workspace root. Set it yourself when that root sits so high above your app that every external home gets long. Under webpack and Rspack the same root is found by climbing up from context to the nearest pnpm-workspace.yaml, lerna.json or workspaces field.
Parsing every file
Every source file is parsed, and there is no option to stop it. It costs about 0.02 ms per file, paid once per file per dev build. That is what finds export const panel = createPanel() in a file whose own text says nothing about stores.
On Vite 8 the plugin borrows the parser Vite ships. Vite 6 and 7, webpack and Rspack need oxc-parser as a dev dependency.