README
View SourceVitex
Table of Contents
- Introduction
- Features
- Installation
- Usage
- Configuration
- Mix Tasks
- Helper Functions
- Common Use Cases
- Troubleshooting
- Contributing
- License
Introduction
Vitex brings the power of Vite to Phoenix applications, replacing the traditional esbuild setup with a modern, fast, and feature-rich development experience. With Vitex, you get instant hot module replacement (HMR), optimized production builds, and seamless integration with modern frontend frameworks.
Why Vitex?
- ⚡ Lightning Fast HMR: See your changes instantly without page reloads
- 🔧 Zero Configuration: Works out of the box with sensible defaults
- 🎯 Framework Agnostic: Support for React, Vue, Svelte, and vanilla JavaScript
- 📦 Optimized Builds: Automatic code splitting and tree shaking
- 🔥 Modern Development: ES modules, TypeScript, JSX, and CSS modules support
- 🚀 Production Ready: Efficient bundling with rollup under the hood
Features
- ✅ Hot Module Replacement (HMR) - Instant updates without losing state
- ✅ React Fast Refresh - Preserve component state during development
- ✅ TypeScript Support - First-class TypeScript support with zero config
- ✅ Inertia.js Integration - Build SPAs with server-side routing
- ✅ SSR Support - Server-side rendering for better SEO and performance
- ✅ Asset Optimization - Automatic minification, tree-shaking, and code splitting
- ✅ CSS Processing - PostCSS, CSS modules, and preprocessor support
- ✅ Static Asset Handling - Import images, fonts, and other assets
- ✅ Manifest Generation - Production-ready asset manifests with hashing
- ✅ Multiple Entry Points - Support for multiple JavaScript/CSS entry files
- ✅ Phoenix LiveView Compatible - Works seamlessly with LiveView
- ✅ Automatic TLS Detection - Detects and uses local certificates for HTTPS
Installation
Automatic Installation (Recommended)
The easiest way to add Vitex to your Phoenix application is using the automatic installer with Igniter:
- Use the Igniter installer.
mix archive.install hex igniter_new
- Run the installer:
# Basic installation
mix igniter.install vitex
# With React support
mix igniter.install vitex --react
# With TypeScript
mix igniter.install vitex --typescript
# With Inertia.js (includes React)
mix igniter.install vitex --inertia
# With all features
mix igniter.install vitex --react --typescript --tls
The installer will:
- Create
vite.config.js
with appropriate settings - Update
package.json
with necessary dependencies - Configure Phoenix watchers for development
- Update your root layout to use Vite helpers
- Set up asset files for your chosen configuration
Manual Installation
If you prefer manual setup or don't want to use Igniter:
- Add Vitex to your dependencies:
# mix.exs
def deps do
[
{:vitex, "~> 0.1.0"}
]
end
- Create
assets/vite.config.js
:
import { defineConfig } from 'vite'
import phoenix from '../deps/vitex/priv/static/vitex'
export default defineConfig({
plugins: [
phoenix({
input: ['js/app.js', 'css/app.css'],
publicDirectory: '../priv/static',
buildDirectory: 'assets',
hotFile: '../priv/hot',
manifestPath: '../priv/static/assets/manifest.json',
refresh: true
})
],
})
- Update
assets/package.json
:
{
"name": "your_app",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build"
},
"dependencies": {
"vite": "^7.0.0"
}
}
- Update your Phoenix configuration:
# config/dev.exs
config :your_app, YourAppWeb.Endpoint,
watchers: [
node: ["node_modules/.bin/vite", cd: "assets"]
]
- Update your root layout:
# lib/your_app_web/components/layouts/root.html.heex
<!DOCTYPE html>
<html>
<head>
<!-- ... -->
<%= Vitex.vite_client() %>
<%= Vitex.vite_assets("css/app.css") %>
<%= Vitex.vite_assets("js/app.js") %>
</head>
<!-- ... -->
</html>
Usage
Basic Usage
After installation, Vitex provides helper functions for your templates:
<!-- In your root layout -->
<%= Vitex.vite_client() %> <!-- Enables HMR in development -->
<%= Vitex.vite_assets("js/app.js") %>
<%= Vitex.vite_assets("css/app.css") %>
Start your Phoenix server:
mix phx.server
Vite will automatically start in development mode with HMR enabled.
React Support
To use React with Fast Refresh:
<!-- In your layout -->
<%= Vitex.react_refresh() %> <!-- Add before your app scripts -->
<%= Vitex.vite_assets("js/app.jsx") %>
Configure Vite for React:
// vite.config.js
import { defineConfig } from 'vite'
import phoenix from '../deps/vitex/priv/static/vitex'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [
react(),
phoenix({
input: ['js/app.jsx', 'css/app.css'],
reactRefresh: true,
// ... other options
})
],
})
TypeScript Support
Vitex supports TypeScript out of the box:
// vite.config.js
export default defineConfig({
plugins: [
phoenix({
input: ['js/app.ts', 'css/app.css'],
// ... other options
})
],
})
Create assets/tsconfig.json
:
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"lib": ["ES2020", "DOM"],
"jsx": "react-jsx",
"strict": true,
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true
},
"include": ["js/**/*"]
}
Inertia.js Integration
For building SPAs with Inertia.js:
# In your controller
def index(conn, _params) do
conn
|> assign_prop(:users, Users.list_users())
|> render_inertia("Users/Index")
end
// assets/js/pages/Users/Index.jsx
import React from 'react'
export default function UsersIndex({ users }) {
return (
<div>
<h1>Users</h1>
{users.map(user => (
<div key={user.id}>{user.name}</div>
))}
</div>
)
}
Server-Side Rendering (SSR)
Enable SSR in your Vite config:
// vite.config.js
export default defineConfig({
plugins: [
phoenix({
input: ['js/app.js', 'css/app.css'],
ssr: 'js/ssr.js',
// ... other options
})
],
})
Build your SSR bundle:
mix vitex.ssr.build
Configuration
Vite Configuration
The Phoenix Vite plugin accepts the following options:
phoenix({
// Entry files (required)
input: ['js/app.js', 'css/app.css'],
// Output directories
publicDirectory: '../priv/static',
buildDirectory: 'assets',
// Development server
hotFile: '../priv/hot',
detectTls: true, // Auto-detect local certificates
// Build options
manifestPath: '../priv/static/assets/manifest.json',
// Features
refresh: true, // Enable full page reload on blade/heex changes
reactRefresh: true, // Enable React Fast Refresh
// SSR
ssr: 'js/ssr.js', // SSR entry point
})
TLS/HTTPS Setup
Vitex can automatically detect local TLS certificates. Enable with:
phoenix({
detectTls: true,
// ... other options
})
For manual TLS configuration, see the TLS setup guide.
Environment Variables
Vitex respects the following environment variables:
NODE_ENV
- Set to "production" for production buildsVITE_PORT
- Custom Vite dev server portVITE_DEV_SERVER_KEY
- Path to TLS key fileVITE_DEV_SERVER_CERT
- Path to TLS certificate file
Mix Tasks
Vitex provides several Mix tasks:
mix vitex
Run Vite commands directly:
mix vitex build # Build for production
mix vitex dev # Start dev server
mix vitex preview # Preview production build
mix vitex.install
Install and configure Vitex (requires Igniter):
mix vitex.install [options]
Options:
--react Enable React support
--typescript Enable TypeScript
--inertia Enable Inertia.js (includes React)
--tls Enable TLS auto-detection
--ssr Enable SSR support
mix vitex.build
Build assets for production:
mix vitex.build
mix vitex.ssr.build
Build SSR bundle:
mix vitex.ssr.build
Helper Functions
Vitex provides the following helper functions:
Vitex.vite_assets/1
Generate script/link tags for entries:
Vitex.vite_assets("js/app.js")
# In dev: <script type="module" src="http://localhost:5173/js/app.js"></script>
# In prod: <script type="module" src="/assets/app.123abc.js"></script>
Vitex.vite_assets(["js/app.js", "js/admin.js"])
# Generates tags for multiple entries
Vitex.vite_client/0
Enable HMR in development:
Vitex.vite_client()
# In dev: <script type="module" src="http://localhost:5173/@vite/client"></script>
# In prod: <!-- nothing -->
Vitex.react_refresh/0
Enable React Fast Refresh:
Vitex.react_refresh()
# Injects React Refresh runtime in development
Vitex.asset_path/1
Get the URL for an asset:
Vitex.asset_path("images/logo.png")
# In dev: "http://localhost:5173/images/logo.png"
# In prod: "/assets/logo.123abc.png"
Vitex.hmr_enabled?/0
Check if HMR is active:
if Vitex.hmr_enabled?() do
# Development-specific code
end
Common Use Cases
Single Page Applications
Build SPAs with client-side routing:
// vite.config.js
export default defineConfig({
plugins: [
phoenix({
input: ['js/app.jsx'],
// ... other options
})
],
build: {
rollupOptions: {
output: {
manualChunks: {
vendor: ['react', 'react-dom', 'react-router-dom']
}
}
}
}
})
Tailwind CSS
Vitex works great with Tailwind CSS v4:
// vite.config.js
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [
tailwindcss(),
phoenix({
// ... options
})
],
})
Multiple Entry Points
Support multiple sections of your app:
phoenix({
input: [
'js/app.js',
'js/admin.js',
'css/app.css',
'css/admin.css'
],
// ... other options
})
Code Splitting
Vite automatically handles code splitting for dynamic imports:
// Lazy load a component
const AdminPanel = lazy(() => import('./components/AdminPanel'))
// Dynamic import based on route
if (route === '/admin') {
const { initAdmin } = await import('./admin')
initAdmin()
}
Troubleshooting
Common Issues
Vite dev server not starting
- Check that Node.js is installed (v18+ recommended)
- Ensure
assets/package.json
exists - Run
npm install
in the assets directory
Assets not loading in production
- Run
mix vitex.build
before deploying - Check that manifest.json is generated in
priv/static/assets/
- Ensure
priv/static
is included in your release
HMR not working
- Verify Vite dev server is running (check
priv/hot
file) - Check browser console for connection errors
- Ensure
Vitex.vite_client()
is included in your layout
TypeScript errors
- Vite doesn't type-check by default (for speed)
- Use your editor's TypeScript integration
- Run
tsc --noEmit
for full type checking
Getting Help
Contributing
We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
Development Setup
# Clone the repo
git clone https://github.com/nordbeam/vitex.git
cd vitex
# Install dependencies
mix deps.get
cd priv/vitex && npm install
# Run tests
mix test
# Build the Vite plugin
cd priv/vitex && npm run build
License
This project is licensed under the MIT License - see the LICENSE file for details.
Copyright (c) 2025 Nordbeam Team