Building well on CodeIgniter 4
What changed
CodeIgniter 4 was written from scratch. Controllers, models and libraries are ordinary namespaced classes found through PSR-4 autoloading, so the old loader and the global super-object are gone. Configuration lives in classes under the Config namespace, with values overridden per environment through a .env file. The application sits outside the web root, and only the public folder is exposed. Requests and responses are objects. Services are fetched from a central factory, which also makes them replaceable in tests. If you know the older framework, the ideas carry over. The code does not.
Entities keep rules next to data
A model can return plain arrays, and for simple lookups that is fine. For records with behavior we use entity classes. An invoice entity can cast its dates, expose a computed balance and refuse an edit once it is marked as paid. That logic then travels with the record instead of being repeated in every controller that touches invoices. The trade-off is a little more structure up front, which pays back as soon as a second screen needs the same rule.
Filters are the security perimeter
In CodeIgniter 4, route filters run before a controller is reached and after it returns. We declare authentication and permission filters on route groups, so a glance at the routes file shows what is protected. A common mistake is leaving automatic routing switched on, which can expose controller methods nobody meant to publish. We define routes explicitly and keep auto routing off.
Modules for anything beyond small
The framework lets any namespace act as a module with its own controllers, models, views, config, routes and migrations. We split by business area, such as Billing or Scheduling, and never by technical layer. Each module registers its own routes and can be tested alone. This keeps a growing application from collapsing into one crowded app folder, and it is the main thing we look for when reviewing a project another team started.
Shield instead of home-made logins
Shield is the authentication and authorization library maintained by the CodeIgniter team. It covers session logins, access tokens for APIs, groups and permissions, and the account flows people expect, such as registration, email activation and account recovery. We configure it to your roles and extend it where needed. Writing authentication from nothing is rarely justified, and the bugs it produces are the expensive kind. If your team is coming from the previous version, the 3 to 4 upgrade page explains how existing code is carried across.