Upgrading
Instructions for upgrading Wheels applications
Wheels follows Semantic Versioning (semver.org):
Major releases (e.g.,
2.x.x → 3.x.x
) may include breaking changes and require code adjustments.Minor releases (e.g.,
3.0.x → 3.1.x
) may add new features in a backwards-compatible way.Patch releases (e.g.,
3.0.1 → 3.0.2
) focus on bug fixes.
Upgrading an existing application involves more than swapping the wheels
folder — it often requires project restructuring, dependency updates, and code modifications.
General Upgrade Process for Existing Applications
1. Backup First
Create a full backup of your application code and database.
Commit all changes if using version control.
2. Read All Relevant Upgrade Notes
If skipping versions, review the upgrade notes for every version in between.
Some changes require manual adjustments outside the
wheels
folder.
3. Use a Safe Environment
Test upgrades in a local or staging environment before production.
4. Upgrade Steps
Follow the version-specific changes listed below.
Replace/update the
wheels
folder with the version you are upgrading to.Apply all required file moves, renames, and deletions.
Install new dependencies (
box install
if using CommandBox).Update code for removed or renamed functions.
Check plugins for compatibility.
5. Test Thoroughly
Run your test suite.
Fix routing, mappings, or missing dependency issues.
6. Deploy to Production
Clear caches and restart the CFML engine after deployment.
Upgrading to Wheels 3.0.0
This guide walks you through upgrading an existing Wheels application to version 3.0.0. It covers compatibility changes, the new folder structure, and the CommandBox (box.json
) dependency management process for the vendor/
folder.
1. Compatibility Changes
No longer supported: Adobe ColdFusion 2016 and earlier.
Supported engines:
Adobe ColdFusion 2018+ (except Adobe ColdFusion 2025)
Lucee 5+
BoxLang
2. New Folder Structure
Wheels 3.x adopts a more modern and organized structure. Update your application as follows:
2.1 Application Code
Move your app code into a new app/
directory at the root:
app/controllers/
app/global/
app/migrator/
app/models/
app/plugins/
app/views/
2.2 Configurations
Keep the config/
folder at the root.
2.3 Database Migrations
Keep the db/
folder at the root.
2.4 Public Assets
Keep the public/
folder at the root. Move all static assets into public/
:
public/images/
public/files/
public/javascripts/
public/miscellaneous/
public/stylesheets/
2.5 Updated Core Files
Inside public/
, replace the following with the latest versions from Wheels 3.x:
Application.cfc
index.cfm
urlrewrite.xml
3. Vendor Folder Changes — Managed with CommandBox
Wheels 3.x manages its core files and related libraries via CommandBox. This means no manually downloading or replacing vendor files.
3.1 Create or Update box.json
box.json
At your project root, define dependencies and where they should be installed:
{
"name": "wheels-app",
"version": "1.0.0",
"dependencies": {
"wirebox": "^7.0.0",
"testbox": "^5.0.0",
"wheels-core": "^3.0.0-SNAPSHOT"
},
"installPaths": {
"wirebox": "vendor/wirebox/",
"testbox": "vendor/testbox/",
"wheels-core": "vendor/wheels/"
}
}
Explanation:
dependencies
: Lists the packages your app needs, with version ranges.installPaths
: Ensures each dependency installs into a specific folder insidevendor/
.
3.2 Install Dependencies
Run:
box install
This will:
Download
wheels-core
,wirebox
, andtestbox
Place them into the correct
vendor/
subfolders based oninstallPaths
3.3 Check Application Mappings
Ensure Application.cfc
includes mappings for the new locations:
/app
/config
/db
/public
/vendor
/wheels
/wirebox
/testbox
/tests
Mappings must point to the correct folders inside vendor/
so Wheels can find its core files and libraries.
4. Before & After Folder Layout
Before (Wheels 2.x)
/controllers
/global
/migrator
/models
/plugins
/views
/config
/db
/public
/vendor (manual files)
Application.cfc
index.cfm
urlrewrite.xml
After (Wheels 3.x)
/app
/controllers
/global
/migrator
/models
/plugins
/views
/config
/db
/public
Application.cfc
index.cfm
urlrewrite.xml
/vendor
/wheels
/wirebox
/testbox
.env
box.json
server.json
5. Final Steps After Upgrade
Run
box install
to ensure all dependencies are fetched.Review and update
Application.cfc
mappings.Test your application thoroughly.
Check the Wheels 3.x release notes for any breaking changes affecting your code.
Commit the new structure and
box.json
so the setup is reproducible for all team members.
6. Benefits of the New Approach
No manual vendor updates — dependencies are versioned and reproducible.
Easier upgrades —
box update
replaces manual downloads.Consistent environments — the same
box.json
ensures all developers run the same versions.
Upgrading to 2.3.x
Replace the wheels
folder with the new one from the 2.3.0 download.
Upgrading to 2.2.x
Replace the wheels
folder with the new one from the 2.2.0 download.
Upgrading to 2.1.x
Replace the wheels
folder with the new one from the 2.1.0 download.
Code changes
Rename any instances of
findLast()
tofindLastOne()
Changes outside the wheels folder
Create
/events/onabort.cfm
to support theonAbort
method
Upgrading to 2.0.x
As always, the first step is to replace the wheels
folder with the new one from the 2.0 download.
Other major changes required to upgrade your application are listed in the following sections.
Supported CFML Engines
Wheels 2.0 requires one of these CFML engines:
Lucee 4.5.5.006 + / 5.2.1.9+
Adobe ColdFusion 10.0.23 / 11.0.12+ / 2016.0.4+
We've updated our minimum requirements to match officially supported versions from the vendors. (For example, Adobe discontinued support for ColdFusion 10 in May 2017, which causes it to be exposed to security exploits in the future. We've included it in 2.0 but it may be discontinued in a future version)
Changes outside the wheels folder
The
events/functions.cfm
file has been moved toglobal/functions.cfm
.The
models/Model.cfc
file should extendwheels.Model
instead ofWheels
(models/Wheels.cfc
can be deleted).The
controllers/Controller.cfc
file should extendwheels.Controller
instead ofWheels
(controllers/Wheels.cfc
can be deleted).The
init
function of controllers and models must be renamed toconfig
.The global setting
modelRequireInit
has been renamed tomodelRequireConfig
.The global setting
cacheControllerInitialization
has been renamed tocacheControllerConfig
.The global setting
cacheModelInitialization
has been renamed tocacheModelConfig
.The global setting
clearServerCache
has been renamed toclearTemplateCache
.The
updateProperties()
method has been removed, useupdate()
instead.JavaScript arguments like
confirm
anddisable
have been removed from the link and form helper functions (use the JS Confirm and JS Disable plugins to reinstate the old behavior).The
renderPage
function has been renamed torenderView
includePartial()
now requires thepartial
andquery
arguments to be set (if using a query)
Routing
The addRoute() function has been removed in Wheels 2.0 in favor of a new routing API. See the Routing chapter for information about the new RESTful routing system.
A limited version of the "wildcard" route ([controller]/[action]/[key]
) is available as [controller]/[action]
) if you use the new wildcard() mapper method:
mapper()
.wildcard()
.end();
By default, this is limited to GET
requests for security reasons.
Cross-Site Request Forgery (CSRF) Protection
It is strongly recommended that you enable Wheels 2.0's built-in CSRF protection.
For many applications, you need to follow these steps:
In
controllers/Controller.cfc
, add a call to protectsFromForgery() to theconfig
method.Add a call to the csrfMetaTags() helper in your layouts'
<head>
sections.Configure any AJAX calls that
POST
data to your application to pass theauthenticityToken
from the<meta>
tags generated by csrfMetaTags() as anX-CSRF-TOKEN
HTTP header.Update your route definitions to enforce HTTP verbs on actions that manipulate data (
get
,post
,patch
,delete
, etc.)Make sure that forms within the application are
POST
ing data to the actions that requirepost
,patch
, anddelete
verbs.
See documentation for the CSRF Protection Plugin for more information.
Note: If you had previously installed the CSRF Protection plugin, you may remove it and rely on the functionality included in the Wheels 2 core.
Database Migrations
If you have previously been using the dbmigrate plugin, you can now use the inbuilt version within the Wheels 2 core.
Database Migration files in /db/migrate/
should now be moved to /app/migrator/migrations/
and extend wheels.migrator.Migration
, not plugins.dbmigrate.Migration
which can be changed with a simple find and replace. Note: Oracle is not currently supported for Migrator.
Upgrading to 1.4.x
Replace the
wheels
folder with the new one from the 1.4 download.Replace URL rewriting rule files – i.e,
.htaccess
,web.config
,IsapiRewrite.ini
In addition, if you're upgrading from an earlier version of Wheels, we recommend reviewing the instructions from earlier reference guides below.
Upgrading to 1.3.x
If you are upgrading from Wheels 1.1.0 or newer, follow these steps:
Replace the
wheels
folder with the new one from the 1.3 download.Replace the root
root.cfm
file with the new one from the 1.3 download.Remove the
<cfheader>
calls from the following files:events/onerror.cfm
events/onmaintenance.cfm
events/onmissingtemplate.cfm
In addition, if you're upgrading from an earlier version of Wheels, we recommend reviewing the instructions from earlier reference guides below.
Note: To accompany the newest 1.1.x releases, we've highlighted the changes that are affected by each release in this cycle.
Upgrading to 1.1.x
If you are upgrading from Wheels 1.0 or newer, the easiest way to upgrade is to replace the wheels folder with the new one from the 1.1 download. If you are upgrading from an earlier version, we recommend reviewing the steps outlined in Upgrading to Wheels 1.0.
Note: To accompany the newest 1.1.x releases, we've highlighted the changes that are affected by each release in this cycle.
Plugin Compatibility
Be sure to review your plugins and their compatibility with your newly-updated version of Wheels. Some plugins may stop working, throw errors, or cause unexpected behavior in your application.
Supported System Changes
1.1: The minimum Adobe ColdFusion version required is now 8.0.1.
1.1: The minimum Railo version required is now 3.1.2.020.
1.1: The H2 database engine is now supported.
File System Changes
1.1: The .htaccess file has been changed. Be sure to copy over the new one from the new version 1.1 download and copy any addition changes that you may have also made to the original version.
Database Structure Changes
1.1: By default, Wheels 1.1 will wrap database queries in transactions. This requires that your database engine supports transactions. For MySQL in particular, you can convert your MyISAM tables to InnoDB to be compatible with this new functionality. Otherwise, to turn off automatic transactions, place a call to set(transactionMode="none").
1.1: Binary data types are now supported.
CFML Code Changes
Model Code
1.1: Validations will be applied to some model properties automatically. This may cause unintended behavior with your validations. To turn this setting off, call set(automaticValidations=false) in config/settings.cfm.
1.1: The class argument in hasOne(), hasMany(), and belongsTo() has been deprecated. Use the modelName argument instead.
1.1: afterFind() callbacks no longer require special logic to handle the setting of properties in objects and queries. (The "query way" works for both cases now.) Because arguments will always be passed in to the method, you can't rely on StructIsEmpty() to determine if you're dealing with an object or not. In the rare cases that you need to know, you can now call isInstance() or isClass() instead.
1.1: On create, a model will now set the updatedAt auto-timestamp to the same value as the createdAt timestamp. To override this behavior, call set(setUpdatedAtOnCreate=false) in config/settings.cfm.
View Code
1.1: Object form helpers (e.g. textField() and radioButton()) now automatically display a label based on the property name. If you left the label argument blank while using an earlier version of Wheels, some labels may start appearing automatically, leaving you with unintended results. To stop a label from appearing, use label=false instead.
1.1: The contentForLayout() helper to be used in your layout files has been deprecated. Use the includeContent() helper instead.
1.1: In production mode, query strings will automatically be added to the end of all asset URLs (which includes JavaScript includes, stylesheet links, and images). To turn off this setting, call set(assetQueryString=false) in config/settings.cfm.
1.1: stylesheetLinkTag() and javaScriptIncludeTag() now accept external URLs for the source/sources argument. If you manually typed out these tags in previous releases, you can now use these helpers instead.
1.1: flashMessages(), errorMessageOn(), and errorMessagesFor() now create camelCased class attributes instead (for example error-messages is now errorMessages). The same goes for the class attribute on the tag that wraps form elements with errors: it is now fieldWithErrors.
Controller Code
1.1.1: The if argument in all validation functions is now deprecated. Use the condition argument instead.
Upgrading to 1.0.x
Our listing of steps to take while upgrading your Wheels application from earlier versions to 1.0.x.
Upgrading from an earlier version of 1.x? Then the upgrade path is simple. All you need to do is replace the wheels folder with the new wheels folder from the download.
The easiest way to upgrade is to setup an empty website, deploy a fresh copy of Wheels 1.0, and then transfer your application code to it. When transferring, please make note of the following changes and make the appropriate changes to your code.
Note: To accompany the newest 1.0 release, we've highlighted the changes that are affected by that release.
Supported System Changes
1.0: URL rewriting with IIS 7 is now supported.
1.0: URL rewriting in a sub folder on Apache is now supported.
ColdFusion 9 is now supported.
Oracle 10g or later is now supported.
PostgreSQL is now supported.
Railo 3.1 is now supported.
File System Changes
1.0: There is now an app.cfm file in the config folder. Use it to set variables that you'd normally set in Application.cfc (i.e., this.name, this.sessionManagement, this.customTagPaths, etc.)
1.0: There is now a web.config file in the root.
1.0: There is now a Wheels.cfc file in the models folder.
1.0: The Wheels.cfc file in the controllers folder has been updated.
1.0: The IsapiRewrite4.ini and .htaccess files in the root have both been updated.
The controller folder has been changed to controllers.
The model folder has been changed to models.
The view folder has been changed to views.
Rename all of your CFCs in models and controllers to UpperCamelCase. So controller.cfc will become Controller.cfc, adminUser.cfc will become AdminUser.cfc, and so on.
All images must now be stored in the images folder, files in the files folder, JavaScript files in the javascripts folder, and CSS files in the stylesheets folder off of the root.
Database Structure Changes
deletedOn, updatedOn, and createdOn are no longer available as auto-generated fields. Please change the names to deletedAt, updatedAt, and createdAt instead to get similar functionality, and make sure that they are of type datetime, timestamp, or equivalent.
CFML Code Changes
Config Code
1.0: The action of the default route (home) has changed to wheels. The way configuration settings are done has changed quite a bit. To change a Wheels application setting, use the new set() function with the name of the Wheels property to change. (For example, <cfset set(dataSourceName="mydatasource")>.) To see a list of available Wheels settings, refer to the Configuration and Defaults chapter. Model Code
1.0: The extends attribute in models/Model.cfc should now be Wheels.
findById() is now called findByKey(). Additionally, its id argument is now named key instead. For composite keys, this argument will accept a comma-delimited list.
When using a model's findByKey() or findOne() functions, the found property is no longer available. Instead, the functions return false if the record was not found.
A model's errorsOn() function now always returns an array, even if there are no errors on the field. When there are errors for the field, the array elements will contain a struct with name, fieldName, and message elements.
The way callbacks are created has changed. There is now a method for each callback event ( beforeValidation(), beforeValidationOnCreate(), etc.) that should be called from your model's init() method. These methods take a single argument: the method within your model that should be invoked during the callback event. See the chapter on Object Callbacks for an example.
View Code
1.0: The contents of the views/wheels folder have been changed.
The wrapLabel argument in form helpers is now replaced with labelPlacement. Valid values for labelPlacement are before, after, and around.
The first argument for includePartial() has changed from name to partial. If you're referring to it through a named argument, you'll need to replace all instances with partial.
The variable that keeps a counter of the current record when using includePartial() with a query has been renamed from currentRow to current.
There is now an included wheels view folder in views. Be sure to copy that into your existing Wheels application if you're upgrading.
The location of the default layout has changed. It is now stored at /views/layout.cfm. Now controller-specific layouts are stored in their respective view folder as layout.cfm. For example, a custom layout for www.domain.com/about would be stored at /views/about/layout.cfm.
In linkTo(), the id argument is now called key. It now accepts a comma-delimited list in the case of composite keys.
The linkTo() function also accepts an object for the key argument, in which case it will automatically extract the keys from it for use in the hyperlink.
The linkTo() function can be used only for controller-, action-, and route-driven links now. * The url argument has been removed, so now all static links should be coded using a standard "a" tag.
Controller Code
1.0: The extends attribute in controllers/Controller.cfc should now be Wheels. Multiple-word controllers and actions are now word-delimited by hyphens in the URL. For example, if your controller is called SiteAdmin and the action is called editLayout, the URL to access that action would be http://www.domain.com/site-admin/edit-layout.
URL/Routing
The default route for Wheels has changed from [controller]/[action]/[id] to [controller]/[action]/[key]. This is to support composite keys. The params.id value will now only be available as params.key.
You can now pass along composite keys in the URL. Delimit multiple keys with a comma. (If you want to use this feature, then you can't have a comma in the key value itself).
Last updated
Was this helpful?