vinxi
A JavaScript toolkit for composing full-stack apps and frameworks on top of Vite and Nitro.
Repository Health
Technical Analysis
Vinxi is the SDK that SolidStart and other meta-frameworks are built on: it lets you assemble a full-stack JavaScript application (or an entire framework) out of independently configured “routers” rather than shipping one fixed opinion about how dev and prod should work. Each router declares a type — static, http, spa, client, or custom — and Vinxi wires it into a single Vite-powered dev server and a single Nitro-powered production server, so the same createApp call produces a consistent asset manifest, SSR pipeline, and deployment target in both environments.
Under the hood it stitches together two mature but separately-scoped tools: Vite handles bundling, HMR, and the dev-time module graph, while Nitro (the server that also powers Nuxt) handles the universal production server and multi-platform deployment adapters. Vinxi’s job is the wiring in between — manifest generation, file-system routing, server-function/server-component directive plugins, and a CLI (vinxi dev/build) that a framework author can point users at directly.
Because it’s designed to be the substrate under a framework rather than an app framework itself, most day-to-day JavaScript/TypeScript developers meet Vinxi indirectly through SolidStart (and experimentally, AngularStart) rather than importing it directly — but for anyone building their own opinionated meta-framework on Vite, it removes the SSR/SPA/RSC plumbing that would otherwise be reimplemented from scratch.
What You Get
- A
createAppAPI where routers (static, http, spa, client, or custom) are declared as plain config objects and Vinxi resolves, validates, and wires them together - One dev server (Vite-powered) and one production server (Nitro-powered) that share the same manifest and behave consistently across environments
- A file-system router utility and manifest generation for figuring out which client/server assets to load at runtime
- A CLI (
vinxi dev/vinxi build) that framework authors can expose directly to their own users - A hookable lifecycle (
app:created,app:config-resolved,router:created, etc.) for plugging in devtools or custom build steps - Deployment adapters inherited from Nitro, so apps built on Vinxi can target multiple hosting platforms without extra adapter code
- Server-function and server-component directive plugins (
@vinxi/plugin-directives,@vinxi/react-server) for RSC-style and server-action patterns
Common Use Cases
- Building a new opinionated meta-framework (in the style of Next.js or SolidStart) on top of Vite without reimplementing SSR/SPA/asset-manifest wiring
- Composing a full-stack app from multiple router types — a static asset router, an SSR router, and an API router — in one
createAppconfig - Running a SolidStart application, since SolidStart’s dev server, build, and deploy commands are implemented on top of Vinxi
- Adding React Server Components or server-function support to a Vite-based app via Vinxi’s directive plugins
- Deploying a single full-stack app to multiple targets (Node, edge, serverless) by relying on Nitro’s adapters through Vinxi
Under The Hood
Architecture
The core of Vinxi is createApp() in lib/app.js: it takes an array of router configs, validates each against a Zod-backed schema in lib/router-modes.js (routerSchema[router.type].safeParse(...)), resolves them into a single config.routers array, and returns an App object exposing dev(), build(), addRouter(), and a hookable-based hooks emitter (app:created, app:config-resolved). dev() lazily imports lib/dev-server.js to spin up a Vite-powered dev server, while build() imports lib/build.js (the largest module in the package, ~870 lines) to drive Nitro-powered production builds; both paths share the same resolved router config and manifest-generation code under lib/manifest/, which is what keeps dev and prod behavior consistent. Notably, createApp assigns the resulting app to globalThis.app, deliberately mirroring how the object is accessed at runtime in production — a small but telling detail about how tightly dev/prod parity is held together.
Tech Stack
Vinxi is a thin, opinionated layer over two independently-maintained tools: Vite (^6.4.1) for bundling and dev-time HMR, and nitropack (^2.11.10) for the universal production server and its deployment adapters, with h3 and crossws underneath for HTTP/WebSocket handling. Router config validation uses zod ^4, the CLI (bin/cli.mjs) is built on citty, path/routing utilities come from path-to-regexp, radix3, and pathe, and directive-based transforms (for RSC/server-function packages) use @babel/core with custom plugins. The whole thing lives in a pnpm workspace of ~12 published packages (vinxi, @vinxi/router, @vinxi/react-server, @vinxi/plugin-directives, etc.) versioned and released together via Changesets.
Code Quality
Unit test coverage inside the core vinxi package itself is thin — only lib/chunks.test.js and runtime/server.test.ts exist as colocated unit tests. The real safety net is a substantial Playwright-driven end-to-end suite at the repo root (test/*.test.ts) exercising file-system routing, HMR, RSC, sessions, server functions, and multi-SPA setups against real example apps, which is a reasonable approach for a tool whose correctness is mostly about dev/prod runtime behavior rather than pure functions. The codebase is JavaScript with JSDoc-based type annotations (not full .ts) plus generated .d.ts output, uses Prettier for formatting, and CI runs on GitHub Actions (test.yml, autofix.yml) with automated release tagging (version.yml via Changesets) — but there’s no dedicated linter config beyond Prettier, and JSDoc typing gives weaker guarantees than native TypeScript.
What Makes It Unique
Rather than being another meta-framework, Vinxi is the substrate underneath one: its router-type abstraction (static/http/spa/client/custom) lets a framework author declare an entire application’s asset and server topology as data, then get a matching dev server and production server for free. That bet has already been validated in production by SolidStart, which implements its own dev/build commands directly on Vinxi’s App API rather than duplicating Vite/Nitro wiring — making Vinxi less a product for typical app developers and more a proving ground for what a Vite-based meta-framework’s plumbing layer should look like.