Wheels - An open source CFML framework inspired by Ruby on Rails

Latest From the Wheels Dev Blog

Wheels CLI Asset Commands: precompile, clean & clobber

# Introduction So far in this series, we’ve explored how the Wheels CLI in 3.x helps you manage your application’s environments, databases, plugins, and testing workflows. Now we’re discussing another critical aspect of modern web applications: # Asset management. Every production-ready application depends on optimized frontend assets — CSS, JavaScript, images, fonts, and other static resources. During development, assets are often served individually for easier debugging. But in production, they must be optimized for performance. That’s where Wheels CLI asset commands come in. Instead of manually bundling, clearing, or rebuilding static files, Wheels 3.x provides structured commands to manage the asset pipeline directly from your terminal. The CLI now supports: ``` wheels assets precompile wheels assets clean wheels assets clobber ``` These commands transform asset handling from a manual deployment step into a repeatable, production-ready workflow. # Why Asset Commands Matter In real-world applications, asset management affects: * Page load speed * Caching efficiency * SEO performance * Production stability * Deployment reliability Without proper asset control, you may encounter: * Old CSS or JS being cached * Missing compiled files * Conflicts between development and production builds * Bloated static assets * Inconsistent deployments The Wheels CLI asset commands solve these issues with clarity and structure. # wheels assets precompile `wheels assets precompile` This command prepares your assets for production. It typically: * Compiles CSS and JavaScript * Bundles files * Minifies output * Generates fingerprinted filenames * Optimizes static resources When to Use It * Before deploying to staging * Before deploying to production * During CI/CD pipelines * After frontend updates Instead of relying on runtime compilation, precompiling ensures assets are ready before the application goes live. **Benefits** * Faster production performance * Reduced runtime overhead * Improved caching behavior * Stable, predictable deployments Precompilation shifts processing from runtime to build time — which is a best practice in modern web architecture. # wheels assets clean `wheels assets clean` Over time, your compiled assets directory may accumulate outdated files. The **clean** command removes old or unused compiled assets while preserving necessary ones. **Why This Is Important** Without cleaning: * Disk usage grows * Old fingerprinted files remain * Confusion increases during debugging * Deployment directories become cluttered **When to Use It** * After multiple deployments * When troubleshooting asset conflicts * Before running a fresh precompile * During maintenance It keeps your asset directory organized and efficient. # wheels assets clobber `wheels assets clobber` The **clobber** command is more aggressive. It removes all compiled assets completely. Think of it as a full reset. **When to Use It** When assets are corrupted After major frontend restructuring When switching build strategies During deep troubleshooting After running: ``` wheels assets clobber wheels assets precompile ``` You get a completely fresh build from scratch. **Why It’s Powerful** * Eliminates stale artifacts * Removes hidden conflicts * Forces a clean rebuild * Ensures consistency Use it carefully — but confidently. # Example Production Workflow **Before Deployment** ``` wheels assets clean wheels assets precompile ``` **If Something Feels Off** ``` wheels assets clobber wheels assets precompile ``` **CI/CD Example** `wheels assets precompile || exit 1` Automated builds become reliable and predictable. # How These Commands Improve Team Workflows They bring: * Standardized build processes * Cleaner deployment cycles * Faster load times * Reduced caching bugs * Better frontend stability * Easier troubleshooting Instead of manually managing static files, everything is controlled via CLI — just like databases, environments, and plugins. # The Bigger Picture Earlier development workflows often mixed runtime asset handling with manual production steps. Wheels 3.x introduces structured asset lifecycle management. Just like: * Database commands manage data * Environment commands manage configuration * Testing commands ensure quality * Plugin commands extend functionality Asset commands manage performance and deployment consistency. This completes the development lifecycle. # What This Means for Wheels Developers With precompile, clean, and clobber, you gain: * Faster production performance * Reliable build processes * Cleaner deployments * Reduced frontend-related bugs * Better CI/CD automation Assets are no longer an afterthought. They are part of your deployment discipline. # Conclusion The Wheels CLI asset commands in 3.x bring structure to frontend asset management: * `assets precompile` → Prepare for production * `assets clean` → Remove outdated builds * `assets clobber` → Reset everything completely If environment commands help you deploy safely… If testing commands help you ensure quality… If plugin commands help you extend your app… Asset commands help you deliver performance. And in modern web development, performance is not optional — it’s expected. Stay tuned for more deep dives into the evolving Wheels CLI ecosystem.

March 19, 2026 by Zain Ul Abideen

Wheels CLI Plugin Commands: search, install, remove & init

# Introduction So far in this series, we’ve explored how the Wheels CLI in 3.x helps you manage your application key points and main aspects. Now we are discussing one of the strengths of Wheels, which has always been its extensibility. With Wheels 3.x, plugin management has evolved into a complete lifecycle experience within the CLI. In earlier versions of Wheels, we already had plugin-related commands such as: `wheels plugin list` This allowed developers to quickly see which plugins were installed inside an application and verify their presence. However, installation and management were still largely manual processes. Plugins allow you to: * Add reusable functionality * Share common solutions across project * Integrate third-party services * Extend framework behavior * Standardize patterns across teams The framework now provides structured commands to discover, install, remove, and even scaffold plugins — all without leaving your terminal. The CLI now supports: ``` wheels plugins search wheels plugins install wheels plugins remove wheels plugins init ``` This shift brings several advantages: * Centralized plugin discovery * Consistent installation across teams * Clean and safe removal * Faster onboarding for new developers * Ability to scaffold reusable internal plugins * Reduced manual file handling errors Instead of manually downloading, copying, and configuring plugin folders, everything can now be managed directly from the CLI. What used to be a manual setup task is now a structured, repeatable workflow — aligned with modern development practices. # Why Plugin CLI Commands Matter Traditionally, managing plugins meant: * Searching documentation or GitHub manually * Downloading zip files * Copying folders into /plugins * Managing dependencies manually * Removing plugins by deleting directories This process was: * Inconsistent * Error-prone * Hard to standardize across teams The new CLI plugin commands bring: * Discoverability * Automation * Clean installation * Safe removal * Scaffolding for new plugins It makes plugin management modern and developer-friendly. # wheels plugins search **Discover Available Plugins** `wheels plugins search authenticateThis` This command lets you search for available plugins by keyword. Instead of browsing repositories manually, you can: * Search by functionality * Explore plugin descriptions * See available versions * Identify compatible plugins **When to Use It** * Looking for caching solutions * Searching for authentication helpers * Exploring logging enhancements * Finding integrations (payment, email, etc.) It turns plugin discovery into a quick CLI action instead of a research task. # wheels plugins install **Install Plugins Cleanly** `wheels plugins install authenticateThis` This command: * Downloads the plugin * Places it in the correct directory * Handles necessary setup steps * Registers it properly within the app No manual folder copying. No guesswork. **Benefits** * Standardized installation * Reduced setup errors * Faster onboarding * Clear version control For teams, this is huge. Instead of sending plugin files manually, you simply say: `“Run wheels plugins install xyz.”` Consistent. Repeatable. Clean. # wheels plugins remove **Remove Plugins Safely** `wheels plugins remove authenticateThis` Instead of manually deleting plugin directories and hoping nothing breaks, this command: * Removes the plugin cleanly * Updates internal references * Keeps the application structure organized **Why This Matters** Manual removal can leave: * Unused config entries * Stray files * Broken dependencies The CLI ensures a structured uninstall process. Cleaner codebase. Less technical debt. # wheels plugins init **Scaffold Your Own Plugin** `wheels plugins init myCustomPlugin` This command creates the basic structure for a new plugin. It generates: * Required directories * Boilerplate files * Plugin configuration * Proper structure following Wheels conventions **Why This Is Powerful** If your team builds reusable features across multiple apps: * Custom validation logic * Shared integrations * Common business utilities * Internal framework extensions You can now package them as plugins easily. Instead of copying code between projects, you create a proper plugin once — and reuse it everywhere. # Real-World Workflow Example **Discover a Plugin** `wheels plugins search i18n` **Install It** `wheels plugins install wheels-i18n` **Confirm Installation** `wheels plugin list` **Remove If No Longer Needed** `wheels plugins remove wheels-i18n` **Build Your Own** `wheels plugins init companyAuth` Everything stays structured and reproducible. # Team & CI/CD Benefits These commands support: * Faster onboarding * Standardized project setup * Automated plugin installation in pipelines * Cleaner version control * Reduced manual steps For example, in CI: `wheels plugins install paymentGateway` The environment is ready instantly. # The Bigger Evolution of Wheels CLI In older versions, plugin management was mostly manual, with only listing support available. Wheels 3.x expands that capability into: * Plugin discovery * Automated installation * Structured removal * Plugin scaffolding This reflects a broader philosophy shift: The CLI is no longer just for generating controllers and models. It’s becoming: * A project manager * A dependency manager * An automation tool * A development assistant # What This Means for Wheels Developers With search, install, remove, init, and plugin list, you gain: * Faster project setup * Cleaner dependency management * Better reusability * Stronger team consistency * Simplified maintenance Plugins are no longer “extra files.” They are first-class components of your application architecture. And the CLI treats them that way. # Conclusion The Wheels CLI plugin commands in 3.x modernize how developers extend their applications. * `plugins search` → Discover functionality * `plugins install` → Add it cleanly * `plugins remove` → Remove it safely * `plugins init` → Build your own * `plugin list` → Track what’s installed If database commands help you manage data… If testing commands help you ensure quality… Plugin commands help you extend your app intelligently. And in modern development, intelligent extensibility is everything. Stay tuned — more Wheels CLI deep dives are coming.

March 13, 2026 by Zain Ul Abideen

Wheels CLI Testing Commands: run, all, unit, integration, watch & coverage

# Introduction In previous articles, we explored how the Wheels CLI helps you manage environments, configuration, and databases safely in Wheels 3.x. Now we’re stepping into one of the most critical parts of modern development: # Testing automation. Writing tests is important. Running them consistently, efficiently, and intelligently is even more important. Whether you're: * Fixing a bug * Refactoring a model * Building a new feature * Reviewing a pull request * Preparing for deployment * Running CI/CD pipelines You need fast, reliable test execution. That’s where the Wheels CLI testing commands come in: ``` wheels test run wheels test all wheels test unit wheels test integration wheels test watch wheels test coverage ``` These commands transform testing from a manual step into a structured development workflow. # Why CLI-Based Testing Matters Without proper CLI testing tools, developers often: * Run tests inconsistently * Forget to run certain test suites * Skip integration tests * Manually check coverage * Run full test suites unnecessarily * Waste time rerunning everything The Wheels CLI standardizes test execution. It makes testing: * Repeatable * Targeted * Automated * CI-friendly * Developer-friendly Testing becomes part of your daily workflow — not a separate task. # wheels test run Run Tests Quickly `wheels test run` This is your primary test execution command. It runs your default configured test suite. Use it when: * You’ve made changes * You’re about to commit * You’re verifying a bug fix * You’re checking regression impact It’s your go-to command for daily development. # wheels test all **Execute Everything** `wheels test all` This runs: * Unit tests * Integration tests * Full application tests Use it when: * Preparing for deployment * Running CI builds * Verifying a major refactor * Ensuring full system stability This gives you complete confidence before shipping. # wheels test unit **Fast, Focused Feedback** `wheels test unit` Unit tests are: * Fast * Isolated * Focused on small pieces of logic They test: * Models * Services * Helpers * Utility functions Run this when: * Refactoring business logic * Updating model behavior * Testing validation rules * Working on isolated components Unit tests provide rapid feedback. They should run in seconds. # wheels test integration **Test Real Interactions** `wheels test integration` Integration tests validate how components work together. They typically cover: * Controller → Model interactions * Database queries * API endpoints * Authentication flows * Request lifecycles These tests are slower than unit tests — but far more comprehensive. Use them when: * Updating controllers * Modifying routes * Changing database behavior * Adjusting authentication * Testing real request flows Integration tests protect against system-level regressions. # wheels test watch **Continuous Testing During Development** `wheels test watch` This command monitors your project files. When changes are detected, Tests automatically rerun. This creates a powerful development loop: 1. Edit code 2. Save 3. Tests rerun instantly 4. See failures immediately It encourages: * Test-driven development (TDD) * Faster debugging * Immediate feedback * Higher code quality No more manually re-running tests after every change. # wheels test coverage **Measure Code Coverage** `wheels test coverage` Running tests is good. Knowing what they actually cover is better. This command generates a coverage report showing: * Percentage of code covered * Untested files * Uncovered lines * Weak testing areas Coverage helps you: * Identify missing test cases * Improve test completeness * Strengthen critical components * Enforce quality standards It transforms testing from reactive to strategic. # How These Commands Work Together Here’s a modern development workflow: **Daily Development** `wheels test unit` Fast feedback while coding. **After Feature Completion** `wheels test integration` Validate system behavior. **Before Commit** `wheels test run` Quick verification. **Before Deployment** ``` wheels test all wheels test coverage ``` Full confidence check. **During Active Development** `wheels test watch` Continuous feedback loop. Each command serves a specific purpose. Together, they create a complete testing ecosystem. # CI/CD Integration These commands are designed to work seamlessly in pipelines: **wheels test all || exit 1** If tests fail, deployment stops. Add coverage thresholds for quality enforcement: * Require minimum coverage percentage * Block deployment if below standard * Track coverage trends over time This makes testing not just a developer tool — but a deployment safeguard. # The Bigger Picture Older CLI tools focused mainly on scaffolding and generation. Wheels 3.x CLI emphasizes: * Observability * Environment safety * Configuration validation * Database lifecycle management * Automated testing Testing commands elevate the CLI into a full development companion. Modern development requires: * Fast iteration * Automated validation * Confidence before release * Clear quality metrics These testing commands deliver exactly that. # What This Means for Wheels Developers With **run**, **all**, **unit**, **integration**, **watch**, and **coverage**, you gain: * Faster debugging cycles * Stronger code quality * Safer refactoring * CI-ready workflows * Continuous feedback * Measurable quality standards Testing stops being optional. It becomes integrated. And when testing becomes effortless, quality naturally improves. # Conclusion The Wheels CLI testing commands in 3.x bring structure and power to your development workflow: * `test run` → Quick verification * `test all` → Full system validation * `test unit` → Fast, focused checks * `test integration` → Real-world confidence * `test watch` → Continuous feedback * `test coverage` → Quality measurement If database commands help you manage data… If environment commands help you deploy safely… Testing commands help you build with confidence. And in modern development, confidence is everything. Stay tuned — more Wheels CLI deep dives are coming. https://youtu.be/L2Z5bxcgVwE

March 09, 2026 by Zain Ul Abideen

Wheels CLI Database Commands: db create & db drop

# Introduction So far in this series, we’ve explored how the Wheels CLI in 3.x helps you inspect your application, manage configuration, and control environments safely. Now we’re moving into something even more foundational: **database lifecycle management**. Your application might have clean code and perfectly aligned environments — but without a properly provisioned database, nothing works. In a Wheels application, the database is not just storage. It powers: * Migrations * Application data * Session handling * Background jobs * Automated tests * API responses It’s core infrastructure. And whether you're: * Setting up a new project * Onboarding a teammate * Preparing a staging server * Resetting a development database * Cleaning up after automated CI tests You’ll eventually need to create or drop a database. Traditionally, this meant: * Logging into the database server manually * Running raw SQL commands * Managing permissions * Double-checking you weren’t targeting production * Repeating the same setup steps across environments It was manual. It was inconsistent. And sometimes — risky. Wheels CLI simplifies this by using your existing environment and datasource configuration to manage database provisioning directly from your project root safely. That’s where these two powerful commands come in: ``` wheels db create wheels db drop ``` Simple in appearance. Powerful in impact. # Why Database CLI Commands Matter Traditionally, creating or dropping databases meant: * Logging into SQL Server / MySQL / PostgreSQL manually * Running SQL scripts * Managing permissions * Copying credentials * Risking mistakes In team environments, this creates friction: * “What’s the correct database name?” * “Which server do I connect to?” * “Is this staging or production?” * “Did I just drop the wrong database?” The Wheels CLI eliminates this confusion by using your existing environment configuration. It knows: * Your datasource * Your database name * Your environment * Your credentials And it acts accordingly. # wheels db create Create a Database Instantly `wheels db create` This command creates the configured database for your active environment. It reads: * Environment settings * Datasource configuration * Database name * Connection credentials Then it provisions the database automatically. **When to Use db create** New Project Setup: ``` wheels environment show wheels db create ``` Your local database is ready — no manual SQL required. Onboarding a Team Member: Instead of sending setup documentation with SQL instructions: *“Just run wheels db create.”* It standardizes project setup. Automated Test Environments: In CI pipelines: `wheels db create` The database is created dynamically for testing. After tests complete, it can be dropped cleanly. **What Happens Behind the Scenes:** The command: 1. Connects to your DB server 2. Checks whether the database exists 3. Creates it if missing 4. Validates permissions 5. Confirms success It respects your current environment. That means: If you are in development → It creates the development DB. If you are in staging → It creates the staging DB. No cross-environment confusion. # wheels db drop Drops the configured database. This command permanently deletes a database. This is a destructive operation that cannot be undone. `wheels db drop` This command drops the database for the active environment. Used carefully, it’s extremely powerful. Used recklessly, it’s dangerous. That’s why environment awareness is critical. **When to Use db drop** Resetting Development: Need a clean slate? ``` wheels db drop wheels db create ``` Now you have a fresh database. Perfect for schema resets or major refactors. Rebuilding After Migration Changes: If migrations changed significantly: ``` wheels db drop wheels db create wheels db migrate latest ``` You’re back to a fully rebuilt database. CI/CD Cleanup: In automated pipelines: `wheels db drop` Removes temporary test databases after completion. **Safety First: Environment Awareness** Before running db drop, always confirm your environment: `wheels environment show` Dropping a production database accidentally is catastrophic. That’s why best practice is: 1. Confirm environment 2. Validate settings 3. Then execute database commands # Example Safe Workflow Step 1 – Confirm Environment `wheels environment show` Step 2 – Validate Environment `wheels environment validate` Step 3 – Drop (if safe) `wheels db drop` Step 4 – Recreate `wheels db create` This structured process prevents irreversible mistakes. # Real-World Development Scenarios **Scenario 1: Local Development Reset** You’ve been experimenting with schema changes. Your database is messy. Instead of manually cleaning tables: ``` wheels db drop wheels db create ``` Clean slate. Fresh start. Zero manual SQL. **Scenario 2: Staging Server Preparation** Before pushing new features: ``` wheels environment switch staging wheels db create ``` Ensures staging DB exists and matches configuration. **Scenario 3: Automated Testing** Your CI workflow: ``` wheels environment set testing wheels db create wheels test run wheels db drop ``` Fully automated lifecycle. No manual intervention. # How These Commands Improve Team Workflows They: * Standardize database setup * Reduce onboarding friction * Eliminate manual SQL steps * Prevent configuration mismatches * Support automated pipelines * Encourage safe environment practices In modern development, repeatability matters. These commands make database setup repeatable. # The Bigger Philosophy Earlier CLI tools focused on scaffolding code. Wheels 3.x CLI is evolving into: * An environment manager * A configuration validator * A deployment assistant * A database lifecycle controller Applications aren’t just code. They are infrastructure + configuration + environments + data. Managing databases via CLI is a natural evolution. # Important Best Practices Before using database commands: * Always confirm environment * Never drop production unless intentional * Use validation commands * Automate in CI when possible * Keep credentials secure Treat database commands with respect. They’re powerful by design. # Conclusion The new database commands in Wheels CLI 3.x simplify one of the most critical parts of application management. `wheels db create` → Instantly provision databases `wheels db drop` → Cleanly remove databases Together, they: * Speed up development * Simplify onboarding * Enable automation * Support safe workflows * Reduce manual SQL tasks If scaffolding commands help you build faster… Environment commands help you deploy safer… These database commands help you reset, rebuild, and automate smarter. And in modern development, controlled data management is everything. Stay tuned — more Wheels CLI deep dives are coming. Learn more here: https://youtu.be/HYXg5CtxrYQ

March 05, 2026 by Zain Ul Abideen

wheels.dev Goes Public: A Production Wheels 3.0 Application You Can Actually Study

Most framework documentation tells you *how* to build something. The Wheels community site at wheels.dev is something different -- it's a production application built with Wheels 3.0 that you can actually look at, poke around, and learn from. We've made the source public, and this article walks through how the site is built, how it's deployed, and how it comes to life inside a Docker Swarm. ## Why Make the Site Public? Framework examples tend to be toy applications. They show you the syntax but not the patterns. They demonstrate a feature in isolation but never show you how thirty features work together in something real. wheels.dev is a real application with real users. It has a blog system with moderation workflows, user authentication with role-based access control, a documentation viewer, newsletter management, an admin dashboard, and a full API layer. It handles file uploads, session clustering across multiple replicas, transactional email, and error tracking. It's the kind of application that exposes the decisions frameworks force you to make -- and shows how Wheels 3.0 handles them. By making the source public, we're turning the community site into the most comprehensive Wheels 3.0 example that exists. ## The Architecture At its core, wheels.dev follows the MVC pattern that Wheels is built around, but scaled to production complexity. ### Models: 31 ActiveRecord Components The data layer uses Wheels' ActiveRecord ORM with 31 model components. The `Blog` model alone demonstrates associations (`belongsTo` User, `hasMany` Comments, Tags, Categories, and ReadingHistory), validations, callbacks, and soft deletes tracked through `deletedAt` and `deletedBy` columns. The `User` model handles password hashing via bcrypt, role associations, and relationships to everything a user can create or interact with. Other models handle the supporting infrastructure: `RememberToken` for persistent login sessions, `PasswordReset` for email-based recovery flows, `LoginAttempt` for security tracking, `Newsletter` and `NewsletterSubscriber` for email campaigns, `Testimonial` with an approval workflow, and `CachedRelease` for caching ForgeBox release data. The database runs on CockroachDB, accessed through a standard PostgreSQL JDBC driver -- CockroachDB speaks the PostgreSQL wire protocol, so Wheels connects to it like any other Postgres database. The schema is managed entirely through timestamped migration files -- over 20 of them covering 25+ tables with foreign key constraints, indexes, and referential integrity. And yes, we're dogfooding here. Wheels currently supports six databases: MySQL, PostgreSQL, SQL Server, H2, Oracle, and SQLite. Running the community site on CockroachDB is our way of putting a seventh database adapter through its paces in production. Anybody hear a seventh supported database coming? ### Controllers: Three Namespaces Controllers are organized into three distinct namespaces, each serving a different concern: - **`web.*`** handles public-facing pages -- the homepage, blog listing and detail views, guides, documentation, community pages, and authentication flows - **`admin.*`** powers the dashboard for content moderation, user management, settings, newsletter administration, and testimonial approval - **`api.*`** exposes RESTful endpoints for blog content, downloads, and authentication A base `Controller.cfc` provides shared infrastructure: CSRF protection via `protectsFromForgery()`, authentication helpers, role-based access checks, and reusable query methods for fetching blogs with their associated tags, categories, and attachments. ### Routing: RESTful by Convention The routing configuration in `config/routes.cfm` demonstrates Wheels' mapper DSL at scale. API routes live under `/api/v1/` with proper REST verb mapping. The blog supports filtering by category, author, and tag through clean URLs like `/blog/categories/[slug]`. Admin routes are grouped under `/admin/` with consistent CRUD patterns. The guides system supports versioned paths (`/3.0.0/guides/[path]`) for serving documentation across framework releases. ### Views: Server-Rendered with HTMX The view layer uses CFML templates with a main `layout.cfm` that handles page titles, meta tags, and content-specific rendering. Where dynamic interactivity is needed -- loading comments, filtering blog posts, toggling UI states -- the site uses HTMX rather than a JavaScript framework. This keeps the architecture simple: the server renders HTML fragments, and HTMX swaps them into the page without full reloads. ## Features Worth Studying Several features in the codebase demonstrate patterns that go beyond what you'd find in a tutorial. ### Authentication and Session Management User authentication supports registration with email verification, login with bcrypt password hashing, and a "Remember Me" system that stores hashed tokens with user-agent validation. If someone's token doesn't match their current browser fingerprint, the token is invalidated -- a practical defense against session theft. Sessions are configured with a 2-hour timeout and a 30-minute idle logout, with session storage backed by CockroachDB so that sessions persist across container restarts and are shared across all Swarm replicas. The `onRequestStart` event handler checks for idle timeouts and validates remember-me tokens on every request. ### Role-Based Access Control The permission system uses a `User -> Role -> Permission` hierarchy. Controllers check access through methods like `checkAdminAccess()` and `checkRoleAccess()`, gating entire controller actions based on the authenticated user's role. The admin namespace uses before-filters to enforce this consistently. ### Blog Content Workflow Blog posts follow a multi-status lifecycle: Draft, Pending Approval, Approved, and Rejected. Authors create and submit posts; administrators moderate them through the admin dashboard with bulk actions. Comments have their own moderation queue. Reading history and bookmarks are tracked per user. The system generates XML sitemaps and RSS-compatible comment feeds. ### Caching Strategy The site uses a 10-minute RAM cache for frequently accessed queries and a dedicated cache for contributor data that's expensive to fetch from external sources. This caching layer is configured in `config/app.cfm` and works transparently with the ORM. ## How the Site is Deployed The deployment pipeline is triggered by any push to the `main` branch of the wheels.dev repository. Here's what happens. ### Building the Container A GitHub Actions workflow runs on a standard Ubuntu runner. It generates an environment file from encrypted GitHub Secrets -- connection details for the CockroachDB cluster, SMTP credentials for Postmark (transactional email), a Sentry DSN for error tracking, an ID salt for obfuscating database identifiers in URLs, and admin passwords. The workflow installs CommandBox (a CFML build tool and dependency manager), runs `box install` to pull all dependencies including the Wheels core framework, and builds a Docker image. The Dockerfile starts from `ortussolutions/commandbox:lucee6`, adds a PostgreSQL JDBC driver, copies in the application code and a production-tuned `server.json`, and disables the browser auto-launch that CommandBox includes for local development. The image is tagged with both `:latest` and the Git commit SHA, then pushed to GitHub Container Registry. ### Deploying to the Swarm A self-hosted GitHub Actions runner inside the Docker Swarm cluster picks up the deployment job. It authenticates with the container registry and runs `docker stack deploy`, which reconciles the running state with the desired state defined in `docker-compose.yml`. The stack deploys **three replicas** of the application. Rolling updates proceed one container at a time with a 15-second delay, using a start-first strategy -- the new replica must be running and healthy before the old one is removed. Rollbacks follow the same one-at-a-time pattern with a 10-second delay. Each replica gets up to 2 CPUs and 4 GB of memory, with the JVM tuned to a 2 GB minimum and 3 GB maximum heap. A Traefik reverse proxy handles load balancing and routing based on the `Host` header. Because sessions are stored in CockroachDB with clustering enabled, any replica can serve any request -- there's no need for sticky sessions or session affinity cookies. ### Shared Storage One of the trickier aspects of running a stateful web application across multiple replicas is file storage. Uploaded images, file attachments, generated sitemaps, versioned documentation, and API JSON responses all need to be accessible from every replica. The solution is CephFS-backed volumes mounted into each container at specific paths: `/app/public/images`, `/app/public/files`, `/app/public/sitemap`, `/app/docs/3.0.0/guides`, and `/app/public/json`. When a user uploads an image through replica 1, replicas 2 and 3 can serve it immediately. A separate `/data` volume provides general application state storage that persists across deployments. ### The Warmup Sequence This is one of the most important parts of the deployment, and it's easy to overlook. CFML applications running on the JVM suffer from cold-start latency -- the first request to any template triggers compilation, class loading, and JIT warm-up. In a user-facing application, that first request could take several seconds. The `server.json` configuration includes a warmup directive that fires immediately after the server starts, before it begins accepting external traffic: ``` /index.cfm, /blog, /blog/list, /blog/Categories, /guides, /3.0.0/guides, /api, /api/3.0.0/, /docs, /community, /news, /downloads, /login ``` These 13 URLs are hit sequentially with a 5-minute timeout window using a queued request strategy. By the time the replica joins the Swarm's load balancer rotation, every major route has been compiled, the template cache is warm, database connection pools are established, and the JVM has had a chance to JIT-compile the hot paths. The result: users never hit a cold replica. ### The Network Edge External traffic reaches the application through a Cloudflare tunnel, which handles TLS termination, DDoS protection, and edge caching. Inside the Swarm, Traefik routes requests to the three replicas over an overlay network. A middleware rule redirects `www.wheels.dev` to the apex `wheels.dev` domain. ## What Makes It a "Model" Application The term "model application" means something specific here. It's not just that wheels.dev runs on Wheels -- it's that every architectural decision in the codebase represents a recommended pattern. The controller namespacing (`web`, `admin`, `api`) shows how to organize a growing application. The base controller demonstrates cross-cutting concerns like authentication and CSRF protection. The model layer shows associations, validations, and soft deletes working together in a real schema. The routing configuration demonstrates RESTful conventions, versioned API paths, and clean URL patterns. The migration files show incremental schema evolution. The deployment configuration shows how a Wheels application transitions from development to production: environment-specific config overrides, container-based deployment, session clustering, shared storage, and zero-downtime updates. It's the complete picture -- not a tutorial, not a toy, but a running application that developers can study, fork, and learn from. ## Get Involved The wheels.dev source is public. Browse the code, open issues, suggest improvements, or use it as a reference for your own Wheels 3.0 projects. The repository includes a `CLAUDE.md` with AI-assisted development guidance and a comprehensive README to help you get oriented. If the best documentation is working code, then wheels.dev is the best Wheels 3.0 documentation we could write.

March 05, 2026 by Peter Amiri

Behind the Scenes: How a Single Commit Becomes a Running Application Across 40+ Configurations

When a developer opens a pull request against the Wheels framework, it kicks off one of the most comprehensive CI/CD pipelines you'll find in any open-source project. Whether you're a first-time contributor fixing a typo or a core maintainer shipping a new feature, the moment your PR hits the `develop` branch, the same gauntlet runs: dozens of engine and database combinations are tested, four distinct packages are built and published to a package registry, documentation is synced, container images are built, and a production Docker Swarm deployment rolls out -- all without a single manual intervention. You don't need commit access to trigger this. You just need a pull request. This is the story of how that sausage gets made. ## The Scale of the Problem Wheels is a Rails-inspired MVC framework for CFML (ColdFusion Markup Language). Unlike most frameworks that target a single runtime, Wheels supports **eight different server engines** -- Lucee 5, 6, and 7, Adobe ColdFusion 2018, 2021, 2023, and 2025, and the new BoxLang runtime. It also supports **six different databases**: MySQL, PostgreSQL, SQL Server, H2, Oracle, and SQLite. That matrix creates over 40 unique test configurations. Every one of them runs on every commit to the development branch. There are no shortcuts. ## Stage 1: The Test Matrix When a commit lands on the `develop` branch, GitHub Actions fires the `snapshot.yml` workflow, which immediately calls a reusable `tests.yml` workflow. This is where things get interesting. The test matrix spins up parallel jobs for each valid engine-and-database combination. Some pairs are excluded -- Adobe 2018 doesn't support SQLite, for example -- but the remaining combinations all run simultaneously. Each job follows the same sequence: 1. **Start the CFML engine container** on a dedicated port (Lucee 5 gets port 60005, Adobe 2023 gets 62023, and so on) 2. **Start the database container** (except for embedded databases like H2 and SQLite) 3. **Wait for both services** with retry logic to handle cold-start delays 4. **Patch compatibility files** where needed -- Oracle on Adobe engines requires a serialization filter update 5. **Install engine-specific packages** via the CFML package manager 6. **Execute the full test suite** via HTTP, passing the database type as a parameter 7. **Capture and upload results** as JSON artifacts with detailed workflow logs Each engine gets its own purpose-built Docker image. The Lucee images include H2, Oracle JDBC extensions, and SQLite drivers. The Adobe images handle their own package management quirks. BoxLang runs on its own runtime entirely. The test infrastructure treats each engine as a first-class citizen, not an afterthought. If even one of those 40+ jobs fails, the pipeline stops. Nothing gets published until the entire matrix is green. ## Stage 2: Four Packages, One Pipeline Once the test matrix passes, the release pipeline takes over. Wheels isn't distributed as a single monolithic package -- it's split into four distinct artifacts, each with its own purpose: - **Wheels Core**: The framework engine itself -- routing, ORM, controllers, views, and the internal machinery - **Wheels Base Template**: The application scaffold that developers start new projects from - **Wheels CLI**: Command-line tooling for scaffolding, migrations, and development workflows - **Wheels Starter App**: A ready-to-run example application for learning Each package has its own preparation script that assembles the right files, replaces version placeholders (like `@build.version@` and `@build.number@`), and structures the output for publishing. The version string itself carries meaning: `3.0.0` is a stable release, `3.0.0-rc.1` is a release candidate, and `3.0.0-SNAPSHOT` marks bleeding-edge development builds. A build number suffix (e.g., `+1234`) tracks the exact CI run. After preparation, each package goes through validation -- checking that `box.json` manifests parse correctly, file counts match expectations, and version strings are consistent. Only then does the pipeline authenticate with ForgeBox (the CFML package registry) and publish all four packages. The pipeline also builds ZIP archives with MD5 and SHA512 checksums, uploading them as GitHub Actions artifacts and attaching them to GitHub Releases with auto-generated release notes pulled from the changelog. ## Stage 3: Documentation Sync In parallel with package publishing, the pipeline syncs framework documentation to the community website. A dedicated `docs-sync.yml` workflow checks out both the framework repository and the website repository, then uses `rsync` to synchronize: - **Guide content** (Markdown files) flows from the framework's `docs/src/` directory into the website's versioned guides path - **Image assets** are copied additively so that old screenshots aren't accidentally removed - **API documentation** (JSON) is synced to the website's public directory for the interactive API browser If any files changed during the sync, the workflow commits and pushes to the website repository automatically. This triggers the next stage. ## Stage 4: Container Build When the website repository receives a push to `main` -- whether from a documentation sync or a direct code change -- the `swarm-deploy.yml` workflow fires. This is where the application becomes a container. The build job runs on a standard GitHub-hosted Ubuntu runner. It generates an environment file from GitHub Secrets containing database credentials, SMTP configuration for transactional email, a Sentry DSN for error tracking, and various application secrets. It installs CommandBox (the CFML build tool), pulls all dependencies, and builds a Docker image. The base image is `ortussolutions/commandbox:lucee6`, which provides a Lucee 6 runtime managed by CommandBox. The Dockerfile layers on a PostgreSQL JDBC driver, copies the application code, and includes a production-tuned `server.json` that configures JVM heap sizes, connection pools, and the server warmup sequence. The resulting image gets tagged twice -- once with `:latest` and once with the Git commit SHA for traceability -- then pushed to GitHub Container Registry (GHCR). ## Stage 5: Swarm Deployment The final stage runs on a self-hosted GitHub Actions runner that lives inside the Docker Swarm cluster itself. This runner authenticates with GHCR, pulls the freshly-built image, and executes `docker stack deploy`. The Swarm configuration deploys **three replicas** of the application behind a Traefik reverse proxy. Rolling updates proceed one replica at a time with a 15-second delay between each, using a start-first strategy -- meaning the new container must be healthy before the old one is removed. This ensures zero-downtime deployments. Each replica is allocated up to 2 CPUs and 4 GB of memory, with reserved minimums of 0.25 CPUs and 1 GB to guarantee baseline performance. The JVM is tuned with a 2 GB minimum and 3 GB maximum heap, sized to fit comfortably within the container's memory limit. Sessions are stored in the database with clustering enabled, so any replica can serve any request -- no sticky sessions required. Traefik handles load balancing and TLS termination, while a Cloudflare tunnel provides the public-facing edge with DDoS protection and global CDN caching. Shared storage volumes backed by CephFS allow all three replicas to access the same uploaded images, file attachments, generated sitemaps, and documentation content. This is critical -- without shared storage, a file uploaded through one replica would be invisible to the others. ## The Full Picture Here's what happens in the roughly 15-20 minutes between a developer pushing to `develop` and the changes being live: ``` git push origin develop | v GitHub Actions: snapshot.yml | v 40+ parallel test jobs (8 engines x 6 databases) | v (all green) +---> Package 4 artifacts (core, base, cli, starter-app) +---> Validate and publish to ForgeBox +---> Upload to GitHub Releases with checksums +---> Sync documentation to wheels.dev repo | v wheels.dev repo receives push | v Build Docker image on ubuntu-latest | v Push to GitHub Container Registry | v Self-hosted runner deploys to Docker Swarm | v 3 replicas with rolling updates | v Live at wheels.dev ``` ## Why This Matters For a framework that promises to run anywhere -- on any supported engine, against any supported database -- the CI/CD pipeline is the proof. It's not enough to claim compatibility; every commit verifies it across every combination. The four-package distribution model means developers install only what they need. The automated documentation pipeline means the website is never stale. The container-based deployment with rolling updates means releases happen without anyone noticing downtime. Is this level of orchestration overkill for an open-source CFML framework? Maybe. But for the developers who depend on Wheels in production, knowing that every commit survives a gauntlet of 40+ test configurations before it ever reaches them -- that's not overkill. That's trust.

March 03, 2026 by Peter Amiri

Wheels CLI Environment Commands: set, show, merge, switch & validate

# Introduction In our previous deep dives, we explored how the Wheels CLI helps you inspect your application and validate configuration. Now we’re focusing on something even more critical: # Environment management. Modern applications don’t run in just one mode. They operate across: * development * testing * staging * production * maintenance Managing these environments safely and consistently is essential — especially in Wheels 3.x. This article explores five powerful environment-focused commands: * wheels environment set * wheels environment show * wheels environment merge * wheels environment switch * wheels environment validate These commands are about control, safety, and clarity. Because in real-world development, environment mistakes are expensive. # Why Environment Management Matters Environment confusion causes real problems: * Debug mode accidentally enabled in production * Production database credentials used locally * Caching disabled in staging * Environment variables not loaded correctly * CI/CD pipelines pointing to the wrong configuration These mistakes aren’t code issues. They’re environment issues. The new environment commands in Wheels CLI are designed to prevent exactly that. # wheels environment show **See Your Active Environment Instantly** `wheels environment show` This command tells you: * Which environment is currently active * How it was detected * Which configuration files are being loaded * Relevant environment variables No guessing. No assumptions. If something feels “off,” this is your first command. **Why environment show Is Important** You might think you're in staging. But are you really? Running: `wheels environment show` Confirms it immediately. This prevents: * Accidental deployments * Incorrect database connections * Misaligned debugging settings Clarity before action. # wheels environment set **Explicitly Define Your Environment** `wheels environment set staging` This command allows you to explicitly define the active environment. Instead of relying only on system variables or automatic detection, you can directly control it. **When to Use environment set** * Preparing for deployment * Testing production-like behavior locally * Simulating staging configuration * Overriding default detection temporarily It gives you precision. **Why It Matters** Sometimes environment detection depends on: * Server variables * Hostnames * System environment variables * CI/CD configuration If those aren’t set correctly, unexpected behavior occurs. **environment set** eliminates uncertainty. You choose the environment. # wheels environment switch **Seamlessly Move Between Environments** `wheels environment switch production` While **set** defines the environment, **switch** is optimized for fast transitions during development workflows. Think of it as: * Quick toggling between dev and staging * Testing configuration differences * Reproducing environment-specific bugs **Real-World Scenario** You discover a bug that only happens in production. Instead of deploying blindly: `wheels environment switch production` Now your local app mirrors production behavior. You debug confidently. Then switch back: `wheels environment switch development` Fast. Controlled. Safe. # wheels environment merge **Combine Environment Configurations** `wheels environment merge staging production` The `merge` command allows you to merge configuration values from one environment into another. This is powerful during: * Preparing staging to match production * Promoting tested configuration forward * Synchronizing environment improvements **Why environment merge Is Powerful** Instead of manually copying configuration changes: * It standardizes updates * Reduces human error * Ensures consistency * Speeds up promotion workflows This is especially useful in structured release processes. Example Workflow 1. Test new config in staging 2. Validate everything works 3. Run: `wheels environment merge staging production` Now production inherits the verified configuration. Clean promotion. Less risk. # wheels environment validate **Protect Against Environment Mistakes** `wheels environment validate` This command checks: * Required environment variables exist * Critical settings are properly defined * Production safeguards are enabled * No unsafe debug flags are active * Database connections match expectations Think of it as an environment safety audit. **When to Use environment validate** Before Deployment Always run: `wheels environment validate` Especially before production deployments. It can prevent: * Debug mode in production * Missing secret keys * Incorrect datasource names * Disabled caching **During CI/CD Pipelines** Add it to your automated workflow. If validation fails, deployment stops. That’s modern DevOps discipline. # How These Commands Work Together Here’s a safe environment workflow: Step 1 – Confirm Current Environment `wheels environment show` Step 2 – Switch if Necessary `wheels environment switch staging` Step 3 – Validate Configuration `wheels environment validate` Step 4 – Merge Approved Changes `wheels environment merge staging production` Step 5 – Explicitly Set for Deployment `wheels environment set production` This structured approach prevents environment chaos. # The Bigger Evolution of Wheels CLI Earlier CLI generations focused heavily on: * Generating models * Creating controllers * Scaffolding applications Wheels 3.x is evolving beyond scaffolding. It now emphasizes: * Observability * Configuration management * Environment safety * Deployment confidence Modern development isn’t just about writing code. It’s about managing complexity. And environments are a major source of that complexity. These commands bring order to it. # What This Means for Wheels Developers With **set**, **show**, **merge**, **switch**, and **validate**, you gain: * Explicit environment control * Faster debugging * Safer deployments * Cleaner promotion workflows * Reduced configuration drift * Stronger team collaboration Environment mistakes are subtle — but costly. These commands dramatically reduce that risk. # Conclusion The new environment commands in Wheels CLI 3.x transform how you manage application modes. * environment show gives clarity * environment set gives control * environment switch gives speed * environment merge gives consistency * environment validate gives safety If earlier CLI commands helped you build faster… And inspection commands helped you debug smarter… These environment tools help you deploy safer. And in modern software development, safe environments mean stable applications. Stay tuned — more deep dives into Wheels CLI are coming.

March 02, 2026 by Zain Ul Abideen

Wheels CLI Config Commands: check, diff & dump

# Introduction In our previous article, Wheels CLI Essentials: Inspect Your App with about & get Commands, we explored how Wheels 3.x helps you understand your application's runtime state. Those commands focused on visibility. Now we go one layer deeper. This article introduces three powerful configuration-focused commands: * wheels config check * wheels config diff * wheels config dump These commands are not about what is running. They’re about how your configuration is structured, validated, and compared. If **about** and **get** gave you awareness, these commands give you control. # Why Configuration Commands Matter In modern applications, configuration complexity grows quickly: * Multiple environments * Default framework settings * Custom overrides * Team-specific environment variables * CI/CD configuration differences * Production hotfixes Over time, small configuration mismatches can cause major issues: * “It works on my machine.” * Staging behaves differently from production. * A default value overrides a custom setting. * A config file was edited but not deployed. The new config commands are built to prevent exactly these problems. They give you validation, comparison, and export tools — directly from the CLI. # wheels config check **Validate Your Configuration with Confidence** `wheels config check` The **check** command validates your configuration setup and ensures: * Required settings exist * No invalid configuration keys are present * Environment files are structured correctly * Overrides are applied properly * No conflicting definitions exist Think of it as a configuration health check. **When to Use config check** Before Deployment: Run it before pushing to staging or production: `wheels config check` This ensures: * No missing environment settings * No accidental debug flags * No incomplete overrides It acts like a pre-flight checklist. After Updating Configuration: Changed a config file? Added a new environment variable? Run: `wheels config check` It confirms everything is wired correctly. Why config check Is Powerful: * Prevents runtime configuration errors * Catches typos in setting names * Validates environment consistency * Encourages safe deployment practices Instead of discovering configuration errors in production… You catch them instantly. # wheels config diff **Compare Configuration Across Environments** `wheels config diff development production` The diff command compares configuration values between environments. It shows: * What differs * What exists in one environment but not another * What values are overridden This is extremely valuable in multi-environment workflows. **Why config diff Matters** Environment mismatches are one of the most common causes of bugs. Examples: * Caching enabled in production but not staging * Different datasource names * Different mail server settings * Logging levels not aligned Instead of manually comparing config files, run: `wheels config diff staging production` You instantly see differences in a clean, structured output. **Real-World Scenario** You deploy to production. Something behaves differently from staging. Instead of guessing: `wheels config diff staging production` Now you know: * Exactly what changed * Whether a setting was missed * Whether a production override is affecting behavior This command alone can save hours of manual inspection. **Why config diff Is Essential** * Eliminates manual file comparisons * Prevents environment drift * Improves team collaboration * Simplifies debugging In larger teams, configuration drift is inevitable. This command keeps environments aligned. # wheels config dump Export Your Full Configuration Snapshot `wheels config dump` The **dump** command outputs your complete resolved configuration. It includes: * Default framework settings * Application-level overrides * Environment-specific settings * Fully merged configuration values Think of it as a raw configuration export. **When to Use config dump** Auditing: Need to see everything at once? `wheels config dump` You get a complete configuration snapshot. **Debugging Complex Overrides** Sometimes a setting comes from: * Framework defaults * settings.cfm * Environment-specific files * System environment variables Instead of tracing multiple layers manually, dump shows the final resolved result. **Sharing Configuration Safely** When collaborating with teammates, you can: * Dump configuration * Review it together * Identify unexpected overrides It creates transparency. **Why config dump Is Valuable** Full visibility into final configuration state * Simplifies advanced debugging * Helps audit production setups * Encourages configuration discipline It removes ambiguity. # How These Commands Work Together Here’s a practical workflow: **Step 1 – Validate** `wheels config check` Ensure configuration structure is correct. **Step 2 – Compare** `wheels config diff staging production` Identify environment differences. **Step 3 – Export Snapshot** `wheels config dump` Review the full resolved configuration. Together, they form a powerful configuration management toolkit. # The Bigger Shift in CLI Philosophy Earlier versions of CLI tools focused primarily on: * Generating controllers * Creating models * Scaffolding applications Wheels 3.x is expanding beyond scaffolding. It’s becoming: * A configuration validator * An environment consistency enforcer * A debugging assistant * A deployment safety layer This shift reflects modern development needs. Applications today are not just code. They are configuration-driven systems. And configuration must be inspectable, verifiable, and comparable. # What This Means for Wheels Developers With config check, config diff, and config dump, you gain: * Safer deployments * Fewer environmental surprises * Faster debugging cycles * Better team collaboration * Stronger production confidence These are not flashy commands. They don’t generate files. They don’t create scaffolds. But they solve real-world development problems — the kind that cost time, trust, and production stability. # Conclusion The new configuration commands in Wheels CLI 3.x are small additions — but major upgrades to your workflow. * **wheels config check** protects you from configuration mistakes * **wheels config diff** prevents environment drift * **wheels config dump** gives you full transparency If previous CLI commands helped you build faster… These help you deploy more safely. And in modern software development, safe deployments are everything. Stay tuned — the next deep dive into Wheels CLI is coming. Learn more here: https://youtu.be/6RJWe3RQp1Q

February 26, 2026 by Zain Ul Abideen

Wheels CLI Essentials: Inspect Your App with about & get Commands

# Introduction In our previous article, [Wheels CLI: Modern Commands for Faster, Smarter Wheels 3.0 Development](https://wheels.dev/blog/wheels-cli-modern-commands-for-faster-smarter-wheels-3-0-development), we introduced the new generation of CLI capabilities coming to Wheels 3.x. That article focused on the big picture — how the CLI is evolving beyond scaffolding into a complete development companion. Now it’s time to zoom in. This article explores three powerful inspection commands that help you understand your application’s current state instantly: * wheels about * wheels get environment * wheels get settings These commands are not about generating code. They’re about visibility, awareness, and confidence. When debugging, deploying, or supporting an application, knowing your environment and configuration matters just as much as writing good code. # Why App Inspection Commands Matter Modern development environments are rarely simple. You may have: * Multiple environments (development, staging, production) * Different configuration overrides * Environment-specific settings * Multiple framework versions across projects * Team members working on different machines Without proper visibility, confusion happens quickly. Questions like: * “Which environment am I in?” * “Is caching enabled here?” * “Why is this behaving differently in staging?” * “What version of Wheels is this app using?” The new CLI inspection commands answer these instantly. * No digging through files. * No guessing. * No assumptions. Just clarity. # wheels about **Your Application’s Full Snapshot** The about command provides a complete overview of your Wheels application. `wheels about` It displays: * Wheels framework version * CFML engine information * Application name * Current environment * Configuration status * Key runtime details * Application statistics Think of it as your application’s diagnostic summary. **When to Use about** Debugging Issues: If something behaves unexpectedly, start with: `wheels about` You’ll quickly see: * Whether you’re in the correct environment * Which framework version is running * Whether configuration values are being picked up properly Support & Collaboration: When helping a teammate, the first question often is: “What version are you running?” Instead of manually checking files, they can simply run: `wheels about` It standardizes the way teams share environment information. Deployment Validation: After deploying to staging or production, you can verify: * Correct environment detection * Correct configuration loading * Framework version consistency It’s a fast sanity check before declaring deployment success. Why about Is Powerful: * Reduces troubleshooting time * Prevents environment confusion * Makes support conversations easier * Encourages environmental awareness It’s your first command when something feels “off.” # wheels get environment **Know Exactly Where You Are** Modern apps typically run in multiple environments: * development * testing * staging * production * maintenance The get environment command tells you exactly which one your app is currently using. `wheels get environment` **What It Shows** * Active environment name * How it was detected * Where the configuration is coming from This eliminates guesswork. No more manually inspecting configuration files. **Why This Is Important** Environment mismatches are one of the most common causes of bugs. For example: * Caching enabled in staging but not locally * Different database connections * Different mail server settings * Debug mode accidentally enabled in production Instead of wondering, just run: `wheels get environment` Instant clarity. **Real-World Scenario** Imagine deploying to staging and noticing unexpected behavior. You assume it’s running in staging. But what if the environment variable wasn’t set correctly? Running: `wheels get environment` Immediately confirms whether your assumption is correct. This command alone can save hours of debugging. # wheels get settings **Inspect Your Active Configuration** The get settings command shows the current Wheels application settings for your active environment. `wheels get settings` It displays: * All active configuration values * Default settings * Custom overrides * Environment-specific configurations You can also filter for specific settings if needed. **Why This Command Is Critical** Configuration issues are subtle. Sometimes: * A setting exists in one environment but not another * A default value is overriding a custom one * A configuration file isn’t being loaded as expected Instead of manually opening multiple config files, this command aggregates everything into one clear output. **Practical Use Cases** Troubleshooting: If something related to caching, sessions, or routing behaves differently: `wheels get settings` You’ll immediately see: * What’s enabled * What’s disabled * What values are active Configuration Validation: Before going live: * Confirm debugging is disabled * Confirm production caching is enabled * Confirm mail settings are correct * Confirm custom overrides are loaded This command provides verification without manual inspection. The Bigger Picture: These commands represent an important shift in the CLI philosophy. Older CLI commands focused on generating files. These new commands focus on observability and awareness. They help you: * Understand your app * Validate your configuration * Debug faster * Avoid environment confusion * Collaborate more efficiently In modern development, visibility is productivity. # How These Commands Work Together Here’s a practical workflow: **Step 1 – Confirm Environment** `wheels get environment` Make sure you're in the expected environment. **Step 2 – Inspect Configuration** `wheels get settings` Verify important configuration values. **Step 3 – Full Diagnostic Overview** `wheels about` Review the full application snapshot. Together, they provide a complete picture of your application’s runtime state. # What This Means for Wheels Developers With these inspection tools, Wheels CLI is evolving into more than just a scaffolding tool. It’s becoming: * A diagnostic assistant * A configuration validator * An environment inspector * A debugging companion And this is just the beginning. In upcoming articles, we’ll continue exploring: * Environment management tools * Database utilities * Testing automation commands * Asset workflows * Documentation generation * Advanced plugin tooling Each module builds toward one goal: * More control. * More clarity. * More confidence. # Conclusion The new inspection commands in Wheels CLI 3.x are small in size — but huge in impact. * wheels about gives you a full application snapshot * wheels get environment removes environment guesswork. * wheels get settings exposes active configuration instantly. If earlier CLI commands helped you build faster… These help you debug smarter. And in modern development, smart debugging is just as important as fast coding. Stay tuned — the next deep dive is coming. Learn more here: https://www.youtube.com/watch?v=NHx3-wncyFw

February 23, 2026 by Zain Ul Abideen

Wheels VS Code Extension: Supercharge Your Wheels Development

Wheels has always focused on developer happiness and rapid productivity. But great frameworks deserve great tools — and that’s where the [Wheels VS Code Extension](https://marketplace.visualstudio.com/items?itemName=wheels-dev.wheels-vscode) comes in. This extension transforms Visual Studio Code into a Wheels-aware development environment. Instead of generic editing, you get intelligent assistance designed specifically for Wheels conventions, APIs, and workflows. The result? Less boilerplate. Fewer mistakes. Faster development. Whether you're building a new app or maintaining a large codebase, the extension helps you write cleaner code and move faster with confidence. # Why a Dedicated Wheels Extension Matters Modern development isn’t just about writing code — it’s about: * Speed and efficiency * Consistency across teams * Reducing human error * Discoverability of framework features * Smooth onboarding for new developers The Wheels VS Code Extension addresses all of these by bringing Wheels intelligence directly into your editor. Instead of memorizing function signatures or manually creating files, the extension assists you in real time. # Key Features **File Templates & Scaffolding** Generate Wheels components in seconds using built-in templates that follow best practices. You can instantly scaffold: * Controllers * Models * Views Each template includes common patterns like CRUD actions, validations, associations, and proper CFML structure. How It Helps: * Eliminates repetitive setup * Encourages consistent structure * Saves time during project setup * Great for onboarding juniors You can create components via: * Right-click context menu * Command Palette The extension also creates missing directories automatically. # Quick Code Templates Typing a short keyword expands into a full component structure. **Examples:** * wcontroller → full controller template * wmodel → full model template These templates include: * Associations * Validations * Callbacks * Common CRUD logic Perfect for rapidly building production-ready components. # Function Snippets The extension includes 300+ Wheels functions with smart snippets. You get two options: * Basic version → only required parameters * Full version → all available parameters Benefits: * No more checking docs repeatedly * Tab navigation between parameters * Faster and more accurate coding * Great for learning Wheels APIs # Go To Definition (F12) Instantly jump to related Wheels components. Works with: * Models * Controllers * Routes * Views Examples: * Jump from model("User") to User.cfc * Jump from renderView("users/show") to the view file * Jump from routes to controller actions This is a massive time saver in large projects. # Smart Parameter System A powerful assistance system for function parameters. **Parameter Highlighting** See valid parameters as you type. Quickly discover available options without opening documentation. **Parameter Auto-Completion** Type partial names and auto-complete them instantly. Use when: * wh → where="" * ord → order="" This reduces typos and speeds up development. **Parameter Validation** The extension detects invalid parameter names in real time. If you mistype: `findAll(ordr="name ASC")` You’ll see a warning and a suggestion for the **order**. Why This Matters: * Prevents subtle bugs * Encourages best practices * Helps new developers learn faster * Improves overall code quality **Hover Documentation** Hover over any Wheels function to see: * Parameters * Types * Defaults * Examples * Return values This provides instant documentation without leaving your editor. It’s especially helpful when exploring unfamiliar APIs. # Installation & Setup Getting started is simple: 1. Open Visual Studio Code 2. Go to Extensions (Ctrl+Shift+X for Windows or Cmd+Shift+X for Mac) 3. Search for Wheels 4. Install and reload No configuration required. It works immediately with CFML files. # Troubleshooting **Extension Not Working?** * Ensure file language is set to CFML * Reload the VS Code window **Go To Definition Issues?** * Open your Wheels app as a workspace folder * Follow the standard Wheels structure * Use correct syntax like model("User") **Parameter Hints Missing?** * Press Ctrl+Shift+Space or Cmd+Shift+Space for Windows and Mac respectively * Ensure you're inside a function call **Resources** * Wheels Documentation * Wheels Community Discussions on GitHub * Issue Reporting * Extension Source Code # What This Means for Wheels Developers The Wheels VS Code Extension turns your editor into a Wheels-aware assistant. You get: * Faster scaffolding * Smarter coding * Built-in validation * Better navigation * Instant documentation This reduces context switching and keeps you focused on building features. # Conclusion The Wheels VS Code Extension isn’t just a convenience — it’s a serious productivity upgrade. Developers who use it will: * Write code faster * Make fewer mistakes * Learn the framework more quickly * Maintain cleaner projects * Improve team consistency If Wheels helps you build fast, the VS Code extension helps you build smart. Build faster. Code smarter. Ship better — with Wheels.

February 19, 2026 by Zain Ul Abideen