Vite is a modern frontend build tool that provides an extremely fast development environment and bundles your code for production.
This plugin integrates Vite with a ColdBox backend, handling:
- Dev-server URL injection so ColdBox can load hot-module-replacement assets.
- Asset manifest generation for cache-busted production builds.
- Full-page reload when ColdBox views, layouts, or routes change.
- Support for both the flat (traditional CFML/ColdBox) and BoxLang / tiered application layouts.
The CFML/BoxLang side of the integration is provided by the coldbox-vite ColdBox module, which reads the dev-server URL from the hot file and renders the appropriate <script> / <link> tags.
| Dependency | Version |
|---|---|
| Node.js | ≥ 20.19 |
| Vite | 3, 4, 5, 6, 7, or 8 |
npm install --save-dev vite coldbox-vite-pluginCreate vite.config.js in your project root:
import { defineConfig } from "vite";
import coldbox from "coldbox-vite-plugin";
export default defineConfig({
plugins: [
coldbox("resources/assets/js/app.js"),
],
});Add these scripts to package.json:
"scripts": {
"dev": "vite",
"build": "vite build"
}Then add the coldbox-vite module to your ColdBox app and call vite() from your layout to load the assets.
ColdBox supports two directory structures. Choose the section that matches your project.
The web root is the project root. Handlers, views, and layouts live directly at the top level.
config/
├── ColdBox.cfc
├── Router.cfc
handlers/
views/
layouts/
includes/ ← built assets land here (web-accessible)
resources/
└── assets/
├── js/
│ └── app.js
└── css/
└── app.css
vite.config.js:
import { defineConfig } from "vite";
import coldbox, { refreshPaths } from "coldbox-vite-plugin";
export default defineConfig({
plugins: [
coldbox({
// publicDirectory defaults to "includes"
input: [
"resources/assets/css/app.css",
"resources/assets/js/app.js",
],
refresh: true, // reloads on views/layouts/Router.cfc changes
}),
],
});Built assets are written to includes/build/. The hot file is at includes/hot.
Add to .gitignore:
/includes/build
/includes/hotThe web root is the public/ subdirectory. Application code lives under app/.
app/
├── config/
│ ├── ColdBox.bx
│ └── Router.bx
├── handlers/
├── layouts/
└── views/
public/ ← web root
└── includes/ ← built assets land here (web-accessible)
resources/
└── assets/
├── js/
│ └── app.js
└── css/
└── app.css
vite.config.js:
import { defineConfig } from "vite";
import coldbox, { appRefreshPaths } from "coldbox-vite-plugin";
export default defineConfig({
plugins: [
coldbox({
publicDirectory: "public/includes",
input: [
"resources/assets/css/app.css",
"resources/assets/js/app.js",
],
refresh: appRefreshPaths, // reloads on app/views, app/layouts, app/config/Router.bx
}),
],
});Built assets are written to public/includes/build/. The hot file is at public/includes/hot.
Add to .gitignore:
/public/includes/build
/public/includes/hotcoldbox({
input, // required — entry point(s) to compile
publicDirectory, // default: "includes"
buildDirectory, // default: "build"
ssr, // SSR entry point(s); defaults to `input`
ssrOutputDirectory,// default: "includes/build/ssr"
refresh, // default: false
})| Option | Type | Default | Description |
|---|---|---|---|
input |
string | string[] |
— | Entry point path(s) relative to project root. Required. |
publicDirectory |
string |
"includes" |
Directory where compiled assets are written. Use "public/includes" for the BoxLang/tiered layout. |
buildDirectory |
string |
"build" |
Subdirectory inside publicDirectory for hashed build output. |
ssr |
string | string[] |
input |
Entry point(s) for the SSR bundle. |
ssrOutputDirectory |
string |
"includes/build/ssr" |
Output directory for the SSR bundle. |
refresh |
boolean | string | string[] | RefreshConfig | RefreshConfig[] |
false |
Trigger a full-page reload when matched files change. |
The refresh option wraps vite-plugin-full-reload. It accepts several forms:
// Disable (default)
refresh: false
// Use the built-in paths for your layout:
refresh: true // flat layout — equivalent to refreshPaths
refresh: appRefreshPaths // BoxLang/tiered layout
// Custom glob pattern
refresh: "app/views/**"
// Multiple patterns
refresh: ["app/views/**", "app/layouts/**"]
// Full control
refresh: {
paths: ["app/views/**"],
config: { delay: 300 },
}
// Multiple configurations
refresh: [
{ paths: ["app/views/**"], config: { delay: 300 } },
{ paths: ["app/config/**"] },
]import coldbox, { refreshPaths, appRefreshPaths } from "coldbox-vite-plugin";
// refreshPaths — for flat layout:
// ["layouts/**", "views/**", "config/Router.cfc"]
// appRefreshPaths — for BoxLang / tiered layout:
// ["app/layouts/**", "app/views/**", "app/config/Router.bx"]The plugin automatically registers an @ alias pointing to /resources/assets/js:
import MyComponent from "@/components/MyComponent.js";Override it in vite.config.js if needed:
export default defineConfig({
plugins: [coldbox("resources/assets/js/app.js")],
resolve: {
alias: {
"@": "/resources/assets/ts",
},
},
});import { defineConfig } from "vite";
import coldbox from "coldbox-vite-plugin";
export default defineConfig({
plugins: [
coldbox({
input: "resources/assets/js/app.js",
ssr: "resources/assets/js/ssr.js",
ssrOutputDirectory: "includes/build/ssr",
}),
],
});Add separate build scripts to package.json:
"scripts": {
"dev": "vite",
"build": "vite build && vite build --ssr"
}Use resolvePageComponent from the bundled helper to replace the legacy require() pattern:
import { createInertiaApp } from "@inertiajs/vue3";
import { resolvePageComponent } from "coldbox-vite-plugin/inertia-helpers";
createInertiaApp({
resolve: (name) =>
resolvePageComponent(
`./Pages/${name}.vue`,
import.meta.glob("./Pages/**/*.vue")
),
setup({ el, app, props, plugin }) {
createApp({ render: () => h(app, props) })
.use(plugin)
.mount(el);
},
});| Variable | Description |
|---|---|
ASSET_URL |
CDN or absolute URL prefix prepended to asset paths in production. E.g. https://cdn.example.com. |
Set it in your .env file:
ASSET_URL=https://cdn.example.comBuilt assets will be referenced as https://cdn.example.com/build/<hashed-file>.
import vue from "@vitejs/plugin-vue";
export default defineConfig({
plugins: [
coldbox("resources/assets/js/app.js"),
vue(),
],
});import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [
coldbox("resources/assets/js/app.jsx"),
react(),
],
});Note JavaScript files that contain JSX must use the
.jsxextension.
Install and configure PostCSS:
npx tailwindcss init -pImport Tailwind in your CSS entry point:
@tailwind base;
@tailwind components;
@tailwind utilities;See UPGRADE.md for migration instructions from ColdBox Elixir.
Thank you for considering contributing to the ColdBox Vite plugin! Please open issues and pull requests on GitHub.
The ColdBox Vite plugin is open-sourced software licensed under the MIT license.