https://github.com/rivet-dev/vite-plugin-srvx
https://github.com/rivet-dev/vite-plugin-srvx
Last synced: 4 days ago
JSON representation
- Host: GitHub
- URL: https://github.com/rivet-dev/vite-plugin-srvx
- Owner: rivet-dev
- Created: 2026-01-08T00:12:17.000Z (about 1 month ago)
- Default Branch: main
- Last Pushed: 2026-01-17T05:55:46.000Z (28 days ago)
- Last Synced: 2026-01-18T00:23:56.723Z (27 days ago)
- Language: TypeScript
- Size: 44.9 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# vite-plugin-srvx
A Vite plugin that integrates [srvx](https://srvx.h3.dev/) (Universal Server) with Vite's development server, similar to how `@hono/vite-dev-server` works with Hono.
## Features
- **Automatic index.html serving** - The plugin automatically serves `index.html` on the root path
- **Hot Module Replacement (HMR)** - Full HMR support for your srvx server
- **Automatic Vite client script injection** - Vite's dev client is automatically injected into HTML responses
- **Web Standard APIs** - Use Request/Response APIs that work everywhere
- **Universal** - Works with Node.js, Deno, and Bun
- **Lightning fast** - Powered by Vite's blazing fast dev server
- **Vercel Edge Functions** - Built-in support for deploying to Vercel (auto-detected!)
## Installation
```bash
npm install vite-plugin-srvx srvx vite
```
Or with pnpm:
```bash
pnpm add vite-plugin-srvx srvx vite
```
## Usage
### 1. Create an index.html file
Create an `index.html` file in your project root:
```html
My srvx App
Hello from srvx + Vite!
```
### 2. Create your srvx server
Create a `src/server.ts` file for your API routes:
```typescript
export default {
async fetch(request: Request): Promise {
const url = new URL(request.url)
// The plugin automatically serves index.html on '/'
// so you only need to handle API routes here
if (url.pathname === '/api/hello') {
return Response.json({
message: 'Hello from srvx!',
timestamp: new Date().toISOString(),
})
}
return new Response('Not Found', { status: 404 })
},
}
```
### 3. Configure Vite
Create a `vite.config.ts` file:
```typescript
import { defineConfig } from 'vite'
import srvx from 'vite-plugin-srvx'
export default defineConfig({
plugins: [
...srvx({
entry: './src/server.ts',
}),
],
})
```
### 4. Run the development server
```bash
vite
```
Your srvx server will now run with Vite's dev server! Visit `http://localhost:5173` to see your app:
- `/` - Automatically serves `index.html`
- `/api/hello` - Your srvx API endpoint
- All other routes are handled by your srvx server's fetch handler
## Building for Production
The plugin uses Vite's mode system to handle client and server builds separately.
Add these scripts to your `package.json`:
```json
{
"scripts": {
"dev": "vite",
"build": "vite build && vite build --mode server",
"start": "srvx dist/server.js"
}
}
```
Then build your app:
```bash
npm run build
```
This will:
1. Build your frontend (HTML, CSS, JS) to `dist/public` (first `vite build`)
2. Build your srvx server to `dist/server.js` (second `vite build --mode server`)
Run your production build:
```bash
npm run start
# or directly: srvx dist/server.js
```
srvx automatically serves static files from the `dist/public` directory!
## Options
### Plugin Options
```typescript
interface SrvxOptions {
// Entry file for your srvx server (default: './src/server.ts')
entry?: string
// Output directory for server build (default: 'dist')
outDir?: string
// Server output filename (default: 'server.js')
serverOutFile?: string
// Target framework for deployment (e.g., 'vercel')
// When set to 'vercel' OR when VERCEL=1 env var is set (auto-detected),
// outputs to dist/api/index.js for Vercel Edge Functions
framework?: 'vercel'
// Development server options
// Patterns to exclude from the srvx handler (will be handled by Vite instead)
exclude?: (string | RegExp)[]
// Whether to inject Vite's client script for HMR (default: true)
injectClientScript?: boolean
// Custom module loader (default: uses Vite's ssrLoadModule)
loadModule?: (server: ViteDevServer, entry: string) => Promise
}
```
> **Note:** The plugin returns an array of three plugins (dev server + client build + server build), so use the spread operator: `...srvx({})`
### Example with custom options
```typescript
import { defineConfig } from 'vite'
import srvx from 'vite-plugin-srvx'
export default defineConfig(({ mode }) => ({
plugins: [
...srvx({
entry: './src/server.ts',
outDir: 'build',
serverOutFile: 'app.js',
exclude: [
/.*\.tsx?$/,
/.*\.css$/,
/^\/@.+$/,
],
injectClientScript: true,
}),
],
}))
```
Then build with:
```bash
npm run build
# This runs: vite build && vite build --mode server
# - Client build outputs to build/public
# - Server build outputs to build/app.js
```
And run: `srvx build/app.js` (it will automatically serve static files from `build/public`)
### Using Individual Plugins (Advanced)
If you need more control, you can import the plugins separately:
```typescript
import { defineConfig } from 'vite'
import { devServer, clientBuild, srvxBuild } from 'vite-plugin-srvx'
export default defineConfig(({ mode }) => ({
plugins: [
devServer({ entry: './src/server.ts' }),
clientBuild({ outDir: 'dist' }),
srvxBuild({ entry: './src/server.ts', outDir: 'dist' }),
],
}))
```
## How it works
### Development Mode
The `devServer` plugin creates a Vite middleware that:
1. **Serves index.html on root** - When requesting `/`, the plugin automatically serves and transforms your `index.html` using Vite's `transformIndexHtml` (which handles script injection, etc.)
2. **Intercepts other HTTP requests** - All non-root requests are passed to your srvx server
3. **Loads your srvx server module** - Uses Vite's SSR module loader for HMR support
4. **Converts to Web Standard APIs** - Converts Node.js `IncomingMessage` → Web Standard `Request`
5. **Calls your fetch handler** - Your srvx server's `fetch` handler processes the request
6. **Converts the response** - Converts the `Response` back to Node.js `ServerResponse`
7. **Injects Vite client** - For HTML responses from your server, Vite's client script is injected for HMR
### Production Build
The plugin uses Vite's mode system with three separate plugins:
1. **Client build** (`vite build`):
- `clientBuild` plugin is active (mode !== 'server')
- Builds frontend to `dist/public`
- `srvxBuild` plugin is inactive
2. **Server build** (`vite build --mode server`):
- `srvxBuild` plugin is active (mode === 'server')
- Sets `ssr: true` via the `config` hook
- Builds server to `dist/server.js`
- `clientBuild` plugin is inactive
3. **Run with srvx**:
- `srvx dist/server.js`
- srvx automatically serves static files from `dist/public`
This approach follows the same pattern as [@hono/vite-build](https://github.com/honojs/vite-plugins/tree/main/packages/build)
This gives you the best of both worlds: srvx's universal server API and Vite's lightning-fast development experience!
## Examples
Check out the [examples](./examples) directory for full working examples:
- [examples/basic](./examples/basic) - Basic srvx + Vite setup
- [examples/vercel](./examples/vercel) - Vercel Edge Functions deployment
To run an example:
```bash
pnpm install
pnpm build
cd examples/basic # or examples/vercel
pnpm dev
```
## Comparison with @hono/vite-dev-server
This plugin is heavily inspired by `@hono/vite-dev-server` but designed specifically for srvx:
- Similar middleware architecture
- Same HMR capabilities
- Compatible API design
- Works with any framework that uses Web Standard fetch API
## License
MIT
## Credits
Inspired by [@hono/vite-dev-server](https://github.com/honojs/vite-plugins/tree/main/packages/dev-server)