Skip to content

Start Here

Manual Installation (zip / GitHub)

You don’t need the wheels CLI, CommandBox, or any package manager to run Wheels. Downloading the framework from GitHub and wiring it up by hand is a fully supported path, and in Wheels 4 it’s simpler than it has been in years: two zips, zero external dependencies.

You’ll learn:

  • Which release files to download and exactly where each one goes
  • How to point your web server at the app
  • The one datasource step and the URL-rewriting decision
  • How this differs from the Wheels 3 manual install (it got easier)

Every release publishes its artifacts on the GitHub releases page. For a new app you need exactly two. The names below are from 4.1.2, the current 4.1 release at the time of writing; use the latest release and substitute its version number:

FileWhat it isWhere it goes
wheels-base-template-4.1.2.zipThe application skeleton: app/, config/, public/, tests/, an empty vendor/Extract as your app root
wheels-core-4.1.2.zipThe framework itself — a single wheels/ folderExtract into vendor/, so it becomes vendor/wheels/

That’s the complete list. Wheels 4 has no external dependencies: the DI container (vendor/wheels/Injector.cfc) and the test framework (vendor/wheels/wheelstest/) are built in. .md5/.sha512 checksum files are published alongside each zip if you want to verify downloads.

  1. Extract the base template into your application directory:

    myapp/
    app/
    config/
    db/
    public/
    tests/
    vendor/ (empty — that's expected)
    box.json
    env.example
    server.json

    A zero-byte marker file named wheels-base-template-4.1.2-<timestamp> ships in the zip; it identifies the build and is safe to delete.

  2. Extract the core zip into vendor/. The zip contains a single wheels/ folder, so after extraction you have vendor/wheels/ with Dispatch.cfc, Model.cfc, Controller.cfc, etc. directly inside it. The folder name must be exactly wheels — the mappings in public/Application.cfc depend on it.

  3. Create your .env file. Copy env.example to .env and set at minimum a reload password:

    .env
    WHEELS_ENV=development
    WHEELS_DATASOURCE=wheels
    WHEELS_RELOAD_PASSWORD=pick-something-long

    public/Application.cfc reads this file at startup — no dotenv tooling involved. Never commit it.

  4. Point your web server at public/. The web root is public/ and only public/ — set your IIS site, nginx root, or Apache DocumentRoot there. Everything else (app/, config/, vendor/, .env) sits one level up, unreachable from a browser. The mappings in public/Application.cfc are relative, so the app runs from any disk location. Your CFML engine (Lucee 5/6/7, Adobe ColdFusion 2018–2025, or BoxLang) must be wired to that site the same way as any other CFML app — see CFML Engines for engine specifics and IIS and Windows Deployment for the full IIS walkthrough.

    Give the app its own name, too. The base template’s config/app.cfm ships this.name = "Wheels", and the engine keeps one application scope per name: two apps on the same server that both keep the default share one Wheels application, so the second app runs with the first one’s datasource, routes and migrations. Set a name of your own, such as this.name = "myapp";, before the first request. (Apps generated by the wheels CLI already get the app’s name here.)

  5. Create the datasource. The template ships with set(dataSourceName="wheels") in config/settings.cfm. Register a datasource named wheels in your engine’s admin (Lucee admin or ColdFusion Administrator), or change that line to the name of a datasource you already have. On Adobe ColdFusion, create the datasource in the CF Administrator — runtime-defined datasources are not reliably picked up. On Adobe ColdFusion 2025, install the packages and JDBC driver listed in Adobe ColdFusion 2025 first.

  6. Decide on URL rewriting. The template defaults to set(URLRewriting="On") in config/settings.cfm, which expects your web server to rewrite /posts/1 to /index.cfm/posts/1. The shipped public/urlrewrite.xml handles this only on Tuckey-based servers (what the wheels CLI and CommandBox use) — IIS, nginx, and Apache each need their own rule, covered in IIS and Windows Deployment and VM and Bare-metal Deployment. Until your rewrite rule is in place, set URLRewriting="Partial" — URLs take the /index.cfm/posts/1 form with no server config at all.

  7. Load the app in a browser. You should see the Wheels congratulations page. From here the tutorial and every guide in The Basics apply exactly as written — only the CLI convenience commands differ, and Working Without the CLI maps each one to its no-CLI equivalent.

Adobe ColdFusion 2025 is modular: a fresh install leaves out features that Wheels uses at startup. Before the first request:

  • Install the packages Wheels needs. Without them the first request shows “Wheels failed to initialize” with a message such as The image package is not installed. Install them with cfpm (in cf_root/cfusion/bin), or from the Package Manager page of the ColdFusion Administrator, then restart ColdFusion:

    your shell
    cfpm install image,mail,zip,caching

    Install your database’s package as well (for example mysql), and graphqlclient to stop a startup notice; see Database Configuration.

  • Add the JDBC driver for MySQL. The ColdFusion Administrator’s “MySQL” driver uses com.mysql.cj.jdbc.Driver, which ColdFusion 2025 does not ship; with only the mysql package installed, the datasource fails with No suitable driver. Copy MySQL Connector/J (for example mysql-connector-j-8.4.0.jar) into cf_root/cfusion/lib and restart ColdFusion before you create the datasource.

If you have your own app layout and deployment scripts and only want the framework files: the only hard requirements are (1) vendor/wheels/ present, (2) the six mappings public/Application.cfc defines (/app, /vendor, /wheels, /tests, /config, /plugins), and (3) a web root containing the template’s Application.cfc and index.cfm. Anatomy of a Wheels App documents the full contract. Upgrading later is a vendor/wheels/ swap — see Upgrading Without the CLI.

Prefer git clone over zips? Clone the repo and copy vendor/wheels/ from a release tag:

your shell
git clone --depth=1 --branch v4.1.2 https://github.com/wheels-dev/wheels.git /tmp/wheels-src
cp -R /tmp/wheels-src/vendor/wheels myapp/vendor/wheels

The repo’s vendor/wheels/ at a release tag is the same code as the core zip, with one cosmetic difference: the release pipeline stamps the real version into wheels.json, while a git checkout carries the @build.version@ placeholder — the app runs identically, but version reporting (the debug bar, application.$wheels.version) shows the placeholder-derived value instead of 4.1.2. If exact version metadata matters to you, prefer the zips. (Either way, don’t track the framework from develop in production — tags are the supported line.)