Vite Plugin
@praxisjs/vite-plugin — configures Vite for PraxisJS with decorator support, JSX transform, TypeScript, and optional HMR.
Vite Plugin
The Vite plugin handles everything needed to run PraxisJS: decorator support, the JSX transform to @praxisjs/jsx, and optional component-level HMR. It's required for all PraxisJS projects.
npm install -D @praxisjs/vite-pluginpnpm add -D @praxisjs/vite-pluginyarn add -D @praxisjs/vite-pluginbun add -d @praxisjs/vite-pluginSetup
// vite.config.ts
import { defineConfig } from 'vite'
import { praxisjs } from '@praxisjs/vite-plugin'
export default defineConfig({
plugins: [praxisjs()],
})Options
praxisjs({
hmr: true, // component-level hot reload (default: false)
autoImport: true, // auto-import common decorators (default: false)
})| Option | Type | Default | Description |
|---|---|---|---|
hmr | boolean | false | Enables component-level hot module replacement. The component re-mounts in place without a full page reload when its source file changes. |
autoImport | boolean | false | Auto-imports @Component, @State, @Prop, and other commonly used decorators so you don't have to import them in every file. |
What the plugin does
- Decorator support — sets Vite's oxc transform target to
ES2022, and lowers TC39 decorators with the TypeScript compiler since oxc doesn't support that natively yet - JSX transform — configures Vite to use
@praxisjs/jsxas the JSX import source (equivalent tojsxImportSourcein tsconfig) - HMR — when enabled, patches component classes on save so the instance re-mounts with new logic while preserving existing state where possible
Using decorators in Vitest
Vitest runs test files through Node directly — it doesn't go through Vite's dev/build pipeline unless you wire a plugin into vitest.config.ts. Since decorated classes need the same TC39-to-runtime lowering praxisjs() applies in the browser, import the standalone decoratorLoweringPlugin() export and register it as a Vitest plugin:
// vitest.config.ts
import { defineConfig } from 'vitest/config'
import { decoratorLoweringPlugin } from '@praxisjs/vite-plugin'
export default defineConfig({
plugins: [decoratorLoweringPlugin()],
test: {
environment: 'node', // or 'jsdom' for tests touching the DOM
},
})This is the same plugin praxisjs() includes internally — it only lowers files that contain real decorator syntax, so it's safe to add without also pulling in the JSX transform or HMR pieces, which test files don't need.
Static site generation
For prerendering routes to static HTML at build time (with real client-side hydration), add ssgPlugin() from @praxisjs/ssg alongside praxisjs():
// vite.config.ts
import { praxisjs } from '@praxisjs/vite-plugin'
import { ssgPlugin } from '@praxisjs/ssg'
export default defineConfig({
plugins: [praxisjs(), ssgPlugin({ root: './src/app.tsx' })],
})See the SSG guide for route enumeration, dynamic routes, and how hydration works.
TypeScript configuration
The plugin handles the Vite/oxc side, but TypeScript still needs its own configuration:
// tsconfig.json
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"jsx": "react-jsx",
"jsxImportSource": "@praxisjs/jsx",
"useDefineForClassFields": true,
"strict": true,
"noEmit": true
}
}Tooling
Developer tools for PraxisJS — Vite plugin, in-app DevTools overlay, Storybook adapter, MCP server, and the project scaffolder and maintenance CLIs.
SSG
@praxisjs/ssg — static site generation with real client-side hydration: prerender every route to HTML at build time, then reconcile it into the live DOM on the client instead of discarding it.