Tree state in Rust
EntryStore, walker, watcher, ignore matching, and fuzzy search run natively. JS owns expansion, selection, and scroll — never the canonical tree.
High-performance native primitives for Electron IDEs. A Rust engine walks, watches, and searches; a typed TypeScript client freezes viewport snapshots; React renders half a million rows without breaking a sweat.
EntryStore, walker, watcher, ignore matching, and fuzzy search run natively. JS owns expansion, selection, and scroll — never the canonical tree.
UtilityProcess host, MessagePort sessions, frozen renderer mirrors. Keep the native binary off the main thread and out of the renderer.
Virtualized ARIA tree, soft-duotone icons (plus Material), Git decorations, commands, DnD, and a headless entry under 13 KB gzip — drop into any React 19 app.
Capabilities
From parallel walks and crash-resume to decoration fan-out and compact folders, mille is the filesystem layer you would otherwise re-implement for every product.
jwalk + ripgrep’s ignore crate. Symlink-aware matching skips pnpm store links so monorepo walks stay O(tracked files), not O(store).
notify + 75 ms debounce, rename pairing, volatile-subtree throttling, mutation intent cache so your own edits don’t echo back as storms.
Immutable MirrorSnapshot with stable identity. React concurrent-safe. Bulk bincode path for large viewports.
initialWalk: 'roots-only' paints huge repos in under 200 ms. Children stream when folders expand — no populate-before-ready workaround.
Git, lint, problems, agent-rules — separate decorationVersion so SCM churn never thrash tree caches. Port-side fan-out to every session.
nucleo-powered ranking over the in-memory tree with match indices for highlighting. Content search reserved as a companion package.
Atomic bincode snapshots with parent fsync. Boot from disk, emit events_since diffs, rejoin reality without a cold full walk.
Single-child chains collapse to src/components/ui one-row paths — the IDE pattern users already expect.
Architecture
Engine logic never leaks into NAPI. View state never lives in Rust. The host/client split keeps native code where Electron expects it.
ARIA tree, virtualization, keyboard, rename, DnD, icons, Git badges. Styled or headless.
FileExplorer wrapper, ViewportMirror, deltas, decorations store, React snapshot hook, MessagePort client.
Marshal-only cdylib. Prebuilt .node binaries for eight platform triples via optionalDependencies.
EntryStore, walker, watcher, ignore, search, resume. Unit-testable without Node. Bindable beyond NAPI later.
Packages
Use the engine alone for custom surfaces, or take the full tree UI and be productive in an evening.
Native core + TypeScript client for Node and Electron UtilityProcess hosts.
Drop-in FileTree with VS Code icon theme compatibility and IDE-grade interactions.
Quickstart
Absolute roots only. Construction is cheap — call populateFromRoots() when you want I/O.
# engine + UI pnpm add @vibecook/mille @vibecook/mille-ui # peers for the styled tree pnpm add react react-dom @tanstack/react-virtual
import { FileExplorer } from '@vibecook/mille'; const fx = new FileExplorer({ roots: ['/path/to/workspace'], }); await fx.populateFromRoots(); const snap = fx.getSnapshot(); for (const root of snap.roots()) { console.log(root.id, root.name); } await fx.dispose();
import { FileExplorer } from '@vibecook/mille'; import { FileTree } from '@vibecook/mille-ui'; import '@vibecook/mille-ui/tokens.css'; const fx = new FileExplorer({ roots: ['/path/to/workspace'] }); await fx.populateFromRoots(); export function Sidebar() { return <FileTree fx={fx} ariaLabel="Files" rowHeight={22} />; }
Electron
Main forks the host. Each window gets a MessagePort. The renderer never loads .node.
Full main / host / preload / renderer walkthrough lives in the package embedding guide.
See EMBEDDING.md
and the playground app under apps/playground.
Platforms
The umbrella package resolves the correct binary through optionalDependencies — no postinstall compile step for supported targets.
| Platform | Package |
|---|---|
| macOS arm64 | @vibecook/mille-darwin-arm64 |
| macOS x64 | @vibecook/mille-darwin-x64 |
| Windows x64 | @vibecook/mille-win32-x64-msvc |
| Windows arm64 | @vibecook/mille-win32-arm64-msvc |
| Linux x64 glibc | @vibecook/mille-linux-x64-gnu |
| Linux arm64 glibc | @vibecook/mille-linux-arm64-gnu |
| Linux x64 musl | @vibecook/mille-linux-x64-musl |
| Linux arm64 musl | @vibecook/mille-linux-arm64-musl |
Open the API, clone the playground, or drop mille into your Electron shell tonight.