Step-by-Step Migration Guide
- Prerequisites
- Step 1: Prepare Your Environment
- Step 2: Update Composer Dependencies
- Step 3: Update npm Dependencies
- Step 4: Configure Vite
- Step 5: Migrate Asset Files
- Step 6: Update Configuration
- Step 7: Update Twig Templates
- Step 8: Migrate Custom JavaScript
- Step 9: Update Custom Sprinkles
- Step 10: Database Migrations
- Step 11: Build and Test
- Step 12: Production Deployment
- Troubleshooting Common Issues
- Rollback Plan
- Next Steps
This guide walks you through upgrading an existing UserFrosting 5.1 application to version 6.0. Follow these steps carefully and test thoroughly in a development environment before deploying to production.
Important
Backup Everything: Before starting, create backups of your application code, database, and any user-uploaded files. This upgrade includes breaking changes that may require significant testing.
This guide covers the most common upgrade scenarios, but your specific application may have unique customizations that require additional steps. Always refer to the official documentation if you encounter issues. Also consider whether upgrading in place is the best option for your project, or if a fresh installation of UserFrosting 6.0 with manual migration of custom code and data might be more efficient in the long run.
Prerequisites
Before beginning the upgrade:
- Running latest UserFrosting 5.1.x
- PHP 8.1 or higher installed (8.4 recommended)
- Composer 2 installed
- Node.js 18.0+ installed (LTS 24 recommended)
- npm 9.0+ installed
- Backed up database and application files
- Development environment ready for testing
Step 1: Prepare Your Environment
Update System Requirements
Ensure your development environment meets UserFrosting 6.0 requirements:
# Check PHP version (must be 8.1+)
php -v
# Check Composer version (must be 2.x)
composer --version
# Check Node.js version (must be 18+)
node --version
# Check npm version (must be 9+)
npm --version
If any versions are below requirements, update them before proceeding.
Create a Testing Branch
# Create a new branch for the upgrade
git checkout -b upgrade-to-6.0
# Ensure working directory is clean
git status
Step 2: Update Composer Dependencies
Backup composer.json
cp composer.json composer.json.backup
Update Dependency Versions
Update all userfrosting/* version constraints in composer.json:
Before (5.1):
{
"require": {
"php": "^8.1",
"ext-gd": "*",
"userfrosting/framework": "~5.1.0",
"userfrosting/sprinkle-core": "~5.1.0",
"userfrosting/sprinkle-account": "~5.1.0",
"userfrosting/sprinkle-admin": "~5.1.0",
"userfrosting/theme-adminlte": "~5.1.0"
}
}
After (6.0):
{
"require": {
"php": "^8.1",
"ext-gd": "*",
"userfrosting/framework": "^6.0",
"userfrosting/sprinkle-core": "^6.0",
"userfrosting/sprinkle-account": "^6.0",
"userfrosting/sprinkle-admin": "^6.0"
}
}
The key changes are:
- All
userfrosting/*packages updated from~5.1.0to^6.0 userfrosting/theme-adminlteremoved — the AdminLTE theme is replaced by the new Pink Cupcake theme, which is included as part of the default UserFrosting packages
Run Composer Update
# Update dependencies
composer update
# Clear Composer cache if you encounter issues
composer clear-cache
composer update
Warning
This step may take several minutes as Composer downloads updated dependencies.
Step 3: Update npm Dependencies
Backup package.json
cp package.json package.json.backup
Update npm Dependencies
Replace the contents of your package.json to match the 6.0 structure. The changes are significant — UserFrosting 6 ships a full Vue SPA stack as npm dependencies:
Before (5.1):
{
"dependencies": {
"@userfrosting/sprinkle-admin": "~5.1.0",
"@userfrosting/theme-adminlte": "~5.1.0"
},
"devDependencies": {
"@symfony/webpack-encore": "^5.1.0",
"file-loader": "^6.2.0",
"sass": "^1.51.0",
"webpack-notifier": "^1.14.1"
},
"scripts": {
"dev-server": "encore dev-server",
"dev": "encore dev",
"watch": "encore dev --watch",
"build": "encore production --progress"
}
}
After (6.0):
{
"type": "module",
"engines": {
"node": ">= 18"
},
"dependencies": {
"@userfrosting/sprinkle-account": "^6.0.0",
"@userfrosting/sprinkle-admin": "^6.0.0",
"@userfrosting/sprinkle-core": "^6.0.0",
"@userfrosting/theme-pink-cupcake": "^6.0.0",
"axios": "^1.12.0",
"pinia": "^2.1.6",
"pinia-plugin-persistedstate": "^3.2.0",
"vue": "^3.3.4",
"vue-router": "^4.2.4"
},
"devDependencies": {
"@modyfi/vite-plugin-yaml": "^1.1.1",
"@types/uikit": "^3.14.5",
"@vitejs/plugin-vue": "^5.0.4",
"@vitest/coverage-v8": "^3.1.1",
"@vue/test-utils": "^2.4.6",
"happy-dom": "^20.0.2",
"less": "^4.2.0",
"typescript": "^5.4.5",
"vite": "^6.4.1",
"vite-plugin-vue-devtools": "^7.5.4",
"vitest": "^3.1.1",
"vue-tsc": "^2.1.10"
},
"scripts": {
"vite:dev": "vite",
"vite:build": "vue-tsc && vite build",
"test": "vitest",
"coverage": "vitest run --coverage",
"typecheck": "vue-tsc --noEmit",
"lint": "eslint app/assets/ --fix",
"format": "prettier --write app/assets/"
}
}
Key changes:
@userfrosting/theme-adminlteremoved — replaced by@userfrosting/theme-pink-cupcake@userfrosting/sprinkle-coreand@userfrosting/sprinkle-accountadded as npm packages (they now ship frontend assets)- Full Vue SPA stack added to
dependencies: Vue 3, Vue Router, Pinia, Axios - Webpack Encore and Sass removed, replaced by Vite and Less
- Scripts renamed from Encore (
dev,watch,build) to Vite (vite:dev,vite:build) "type": "module"added to enable native ES modules
Tip
See the skeleton package.json for the complete up-to-date list of dependencies.
Install Dependencies
# Remove old node_modules and lock file
rm -rf node_modules package-lock.json
# Install fresh dependencies
npm install
Step 4: Configure Vite
Create vite.config.ts
Create a new vite.config.ts file in your project root. Use the skeleton's vite.config.ts as your starting point — copy it directly into your project root.
Remove Webpack Configuration
# Remove old Webpack config files
rm webpack.config.js
rm webpack.mix.js # if present
rm -rf app/assets/webpack # if present
Step 5: Migrate Asset Files
Restructure Asset Directory
Before (5.1) structure:
app/assets/
├── webpack.config.js
├── src/
│ ├── app.js
│ └── app.scss
└── public/
└── images/
After (6.0) structure:
app/assets/
├── main.ts # Main entry point
├── theme.less # Main stylesheet
├── components/ # Vue components
│ └── MyComponent.vue
├── css/ # Additional styles
└── public/ # Static assets
└── images/
Create Main Entry Point and App Structure
The app/assets/ directory needs several new files to bootstrap the Vue SPA. Copy the following from the skeleton as your starting point:
app/assets/main.ts— Vue app entry point, sets up Pinia, Router and all sprinkle pluginsapp/assets/App.vue— Root Vue componentapp/assets/router/index.ts— Vue Router configuration, includes routes from all sprinkles
Note
UserFrosting 6 uses Vue Router and Pinia for state management. Each sprinkle registers its own Vue plugin that provides routes, stores, and components. Your custom sprinkle code should extend this setup rather than replace it.
You will likely also want to copy the skeleton's layout and view files as a baseline:
app/assets/layouts/— Page and dashboard layout componentsapp/assets/views/— Default home and about viewsapp/assets/components/— Navbar, sidebar, and footer content placeholders
Rename/Convert Style Files
# Rename SCSS to LESS (or convert if needed)
mv app/assets/src/app.scss app/assets/theme.less
# Or create a new theme.less file
touch app/assets/theme.less
Tip
UIkit uses LESS, so converting your styles to LESS provides better integration. However, Vite also supports SCSS if you prefer to keep it.
Step 6: Update Configuration
Update Configuration Files
The Vite integration is configured through the assets.vite config key. The Core Sprinkle sets sensible defaults, so you only need to customize if your setup differs. The key environment variables are:
# Enable/disable Vite dev server (default: true in development, false in production)
VITE_DEV_ENABLED=true
# Port for the Vite dev server (default: 5173)
VITE_PORT=5173
If you previously had Webpack-related config in app/config/default.php, remove it:
Before (5.1) - remove this:
'assets' => [
'webpack' => [
'manifest' => 'manifest.json'
]
]
The Vite config is handled automatically by the Core Sprinkle. You do not need to add any assets.vite entries to your own config unless you need to customize the server URL or manifest path.
Step 7: Update Twig Templates
Replace Asset Helper Functions
Find and replace all asset loading functions in your Twig templates:
Before (5.1):
{{ encore_entry_script_tags('app') }}
{{ encore_entry_link_tags('app') }}
After (6.0):
{# In your scripts template: #}
{{ vite_js('main.ts') }}
{# In your stylesheets template: #}
{{ vite_css('main.ts') }}
{{ vite_preload('main.ts') }}
Tip
Use find-and-replace in your editor to update all templates at once. Run two separate replacements:
- Find:
encore_entry_script_tags\('([^']+)'\)→ Replace:vite_js('$1.ts') - Find:
encore_entry_link_tags\('([^']+)'\)→ Replace:vite_css('$1.ts')(then add{{ vite_preload('$1.ts') }}on the next line)
Search All Templates
# Find all templates using Encore helpers
grep -r "encore_entry" app/templates/
# Verify no Encore references remain
grep -r "encore" app/templates/
Step 8: Migrate Custom JavaScript
Convert to ES Modules
If you have custom JavaScript, convert it to ES modules:
Before (5.1) - custom.js:
// CommonJS or global scope
var MyModule = {
init: function() {
// ...
}
};
After (6.0) - custom.ts:
// ES Module with TypeScript
export class MyModule {
static init(): void {
// ...
}
}
Update jQuery Code (Optional but Recommended)
If you have jQuery code, consider migrating to Vue 3:
Before (5.1) - jQuery:
$(document).ready(function() {
$('#myButton').on('click', function() {
$('#myDiv').toggle();
});
});
After (6.0) - Vue 3:
<template>
<button @click="toggleDiv">Toggle</button>
<div v-if="showDiv">Content</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const showDiv = ref(false)
const toggleDiv = () => {
showDiv.value = !showDiv.value
}
</script>
Note
jQuery is not included in UserFrosting 6. If you need it during migration, install it manually (npm install jquery). New code should use Vue 3 instead of jQuery for better performance and maintainability.
Step 9: Update Custom Sprinkles
Update Sprinkle Recipe
Verify your sprinkle's Recipe class is compatible with UserFrosting 6.0. Most sprinkle recipes should work without changes, but review the Sprinkles documentation for any API changes.
Step 10: Database Migrations
Run Migrations
UserFrosting 6.0 includes database updates:
# Run migrations
php bakery migrate
# If you encounter issues, rollback and retry
php bakery migrate:rollback
php bakery migrate
Verify Database
Check that all tables are present and properly structured:
# Check migration status
php bakery migrate:status
Step 11: Build and Test
Build Assets
# Build assets for production
npm run vite:build
# Verify build output
ls -la public/assets/
Start Development Servers
Open two terminals:
Terminal 1 - PHP backend:
php bakery serve
Terminal 2 - Vite frontend:
npm run vite:dev
Test Your Application
Visit http://localhost:8080 and thoroughly test:
- Homepage loads correctly
- Login/logout functionality
- User registration
- Admin panel access
- All custom features
- API endpoints
- Forms and validation
- Asset loading (check browser console for errors)
Check Browser Console
Open browser DevTools (F12) and verify:
- No JavaScript errors
- Assets loading correctly (200 status codes)
- No 404 errors for missing files
Step 12: Production Deployment
Build Production Assets
# Build optimized production assets
npm run vite:build
# Verify build output
ls -la public/assets/.vite/
Update Environment Variables
In production .env:
# Disable Vite dev server
VITE_DEV_ENABLED=false
Deploy
Follow your normal deployment process, ensuring:
- Built assets are deployed (
public/assets/) - Dependencies are installed (
composer install --no-dev) - Configuration is set for production
- Database migrations are run
Clear Caches
# Clear all application caches (Illuminate, Twig, and Router cache)
php bakery clear-cache
Troubleshooting Common Issues
"Cannot find module" Errors
Symptom: Vite can't find imported modules
Solution:
# Clear node_modules and reinstall
rm -rf node_modules package-lock.json
npm install
Assets Not Loading
Symptom: 404 errors for assets in browser
Solution:
- Verify
vite.config.tspaths are correct - Check
.envhas correctVITE_DEV_ENABLEDsetting - Ensure Vite dev server is running (development)
- Verify assets are built (
public/assets/) (production)
Vue Components Not Rendering
Symptom: Vue components don't appear on page
Solution:
- Check browser console for Vue errors
- Verify Vue is imported in
main.ts - Ensure components are properly registered
- Check that mounting point (
#app) exists in template
Database Migration Errors
Symptom: Migrations fail to run
Solution:
# Reset and re-run migrations (DEVELOPMENT ONLY)
php bakery migrate:reset
php bakery migrate
# Check migration status
php bakery migrate:status
Performance Issues in Development
Symptom: Slow page loads during development
Solution:
- Ensure Vite dev server is running (
npm run vite:dev) - Check
optimizeDepsinvite.config.ts - Clear Vite cache:
rm -rf node_modules/.vite
Rollback Plan
If you need to rollback to 5.1:
# Restore backups
git checkout main
cp composer.json.backup composer.json
cp package.json.backup package.json
# Reinstall old dependencies
composer install
npm install
# Restore database from backup
# (use your database backup restore process)
Next Steps
After successfully upgrading:
- Review Documentation: Read through the updated Asset Management chapter
- Optimize Assets: Learn about Vite Configuration for performance tuning
- Modernize Code: Gradually convert jQuery to Vue 3 components
- Add TypeScript: Consider adding type safety to your custom code
- Explore Features: Check out new Vite features like HMR and code splitting
If you encounter issues:
- Documentation: UserFrosting Learn
- Community Chat: chat.userfrosting.com
- GitHub Issues: github.com/userfrosting/userfrosting/issues
Congratulations on upgrading to UserFrosting 6.0! 🎉