<div align="center">
<h1 align="center">
Vitex
</h1>
<img src="https://raw.githubusercontent.com/nordbeam/vitex/main/logo.svg" width="200px"/>
[](https://hex.pm/packages/vitex)
[](https://hexdocs.pm/vitex/)
[](https://github.com/nordbeam/vitex/blob/main/LICENSE)
[](https://elixir-lang.org/)
[](https://www.phoenixframework.org/)
**Phoenix integration for Vite - a fast frontend build tool**
[Features](#features) • [Installation](#installation) • [Usage](#usage) • [Configuration](#configuration) • [Documentation](#documentation)
</div>
## Table of Contents
- [Introduction](#introduction)
- [Features](#features)
- [Installation](#installation)
- [Automatic Installation (Recommended)](#automatic-installation-recommended)
- [Manual Installation](#manual-installation)
- [Usage](#usage)
- [Basic Usage](#basic-usage)
- [React Support](#react-support)
- [TypeScript Support](#typescript-support)
- [Inertia.js Integration](#inertiajs-integration)
- [Server-Side Rendering (SSR)](#server-side-rendering-ssr)
- [Configuration](#configuration)
- [Vite Configuration](#vite-configuration)
- [TLS/HTTPS Setup](#tlshttps-setup)
- [Environment Variables](#environment-variables)
- [Mix Tasks](#mix-tasks)
- [Helper Functions](#helper-functions)
- [Common Use Cases](#common-use-cases)
- [Single Page Applications](#single-page-applications)
- [Tailwind CSS](#tailwind-css)
- [Multiple Entry Points](#multiple-entry-points)
- [Code Splitting](#code-splitting)
- [Troubleshooting](#troubleshooting)
- [Contributing](#contributing)
- [License](#license)
## Introduction
Vitex brings the power of [Vite](https://vitejs.dev/) 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](https://github.com/ash-project/igniter):
1. Use the [Igniter](https://hexdocs.pm/igniter) installer.
```sh
mix archive.install hex igniter_new
```
3. Run the installer:
```bash
# 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:
1. Add Vitex to your dependencies:
```elixir
# mix.exs
def deps do
[
{:vitex, "~> 0.1.0"}
]
end
```
2. Create `assets/vite.config.js`:
```javascript
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
})
],
})
```
3. Update `assets/package.json`:
```json
{
"name": "your_app",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build"
},
"dependencies": {
"vite": "^7.0.0"
}
}
```
4. Update your Phoenix configuration:
```elixir
# config/dev.exs
config :your_app, YourAppWeb.Endpoint,
watchers: [
node: ["node_modules/.bin/vite", cd: "assets"]
]
```
5. Update your root layout:
```heex
# 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:
```heex
<!-- 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:
```bash
mix phx.server
```
Vite will automatically start in development mode with HMR enabled.
### React Support
To use React with Fast Refresh:
```heex
<!-- In your layout -->
<%= Vitex.react_refresh() %> <!-- Add before your app scripts -->
<%= Vitex.vite_assets("js/app.jsx") %>
```
Configure Vite for React:
```javascript
// 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:
```javascript
// vite.config.js
export default defineConfig({
plugins: [
phoenix({
input: ['js/app.ts', 'css/app.css'],
// ... other options
})
],
})
```
Create `assets/tsconfig.json`:
```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:
```elixir
# In your controller
def index(conn, _params) do
conn
|> assign_prop(:users, Users.list_users())
|> render_inertia("Users/Index")
end
```
```jsx
// 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:
```javascript
// 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:
```bash
mix vitex.ssr.build
```
## Configuration
### Vite Configuration
The Phoenix Vite plugin accepts the following options:
```javascript
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:
```javascript
phoenix({
detectTls: true,
// ... other options
})
```
For manual TLS configuration, see the [TLS setup guide](priv/vitex/docs/tls-setup.md).
### Environment Variables
Vitex respects the following environment variables:
- `NODE_ENV` - Set to "production" for production builds
- `VITE_PORT` - Custom Vite dev server port
- `VITE_DEV_SERVER_KEY` - Path to TLS key file
- `VITE_DEV_SERVER_CERT` - Path to TLS certificate file
## Mix Tasks
Vitex provides several Mix tasks:
### `mix vitex`
Run Vite commands directly:
```bash
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):
```bash
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:
```bash
mix vitex.build
```
### `mix vitex.ssr.build`
Build SSR bundle:
```bash
mix vitex.ssr.build
```
## Helper Functions
Vitex provides the following helper functions:
### `Vitex.vite_assets/1`
Generate script/link tags for entries:
```elixir
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:
```elixir
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:
```elixir
Vitex.react_refresh()
# Injects React Refresh runtime in development
```
### `Vitex.asset_path/1`
Get the URL for an asset:
```elixir
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:
```elixir
if Vitex.hmr_enabled?() do
# Development-specific code
end
```
## Common Use Cases
### Single Page Applications
Build SPAs with client-side routing:
```javascript
// 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:
```javascript
// vite.config.js
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [
tailwindcss(),
phoenix({
// ... options
})
],
})
```
### Multiple Entry Points
Support multiple sections of your app:
```javascript
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:
```javascript
// 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
- 📚 [Documentation](https://hexdocs.pm/vitex)
- 💬 [Phoenix Forum](https://elixirforum.com/c/phoenix-forum)
- 🐛 [Issue Tracker](https://github.com/nordbeam/vitex/issues)
## Contributing
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
### Development Setup
```bash
# 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](LICENSE) file for details.
Copyright (c) 2025 Nordbeam Team
---
<div align="center">
Made with ❤️ by the Nordbeam Team
</div>