A fast, modular PHP framework for ambitious web applications, APIs and SaaS.
Developed and used in production by Neoground.
Charm is a full-stack PHP framework built around a straightforward idea: provide the infrastructure a serious application repeatedly needs, while keeping the execution model compact, predictable and easy to reason about.
It combines a conventional MVC application structure with attribute-based routing, Twig, Eloquent, YAML configuration, authentication, caching, queues, scheduling, events, storage, HTTP tooling and a modular application system. Applications can stay small, grow into substantial monoliths, or be divided into explicit modules without changing the underlying programming model.
Charm is deliberately compact, not minimal. It is intended for developers who want an integrated framework without making framework machinery the dominant complexity of the application.
Charm is a practical foundation for:
- SaaS and business applications
- APIs and application backends
- server-rendered websites with Twig
- hybrid applications with modern JavaScript frontends
- internal tools and operational platforms
- modular monoliths and reusable application modules
Neoground uses Charm as the foundation for its own web platforms, products and client systems. The framework therefore prioritizes maintainability, operational usefulness and predictable application architecture over abstraction for its own sake.
Charm keeps common application operations close to the code that uses them. Routes can live directly on controller
methods, table definitions can live with models, configuration is accessed through a consistent API, and initialized
framework modules are available through C::.
use Charm\Vivid\C;
$term = C::Request()->get('term');
$hostname = C::Config()->get('connections:database.hostname');
$queue = C::Queue();The same module model extends to custom modules. Charm does not require deep service graphs or runtime controller-parameter resolution for ordinary application code.
The framework includes the recurring systems needed by production applications rather than leaving every project to assemble them independently. That includes routing, requests and responses, views, database access, auth, queues, scheduling, events, cache, storage, mail, validation, logging and development tooling.
The goal is not to hide PHP behind a large abstraction layer. The goal is to remove repetitive infrastructure while keeping application flow visible.
A Charm application can remain one coherent codebase or be split into modules with their own namespaces, configuration
and application structure. Modules are registered through modules.yaml and participate in the same initialization and
runtime model as the framework itself.
This makes it possible to structure a larger application by domain without prematurely turning it into a distributed system.
Charm initializes its modules into a shared application context and uses AppStorage for frequently accessed
lightweight runtime data such as configuration and routing metadata.
For production environments, stable initialization data can be generated into an AppStorage cache. This avoids repeating work that does not need to be rediscovered on every request and keeps framework bootstrapping lean.
| Area | Included |
|---|---|
| Application structure | MVC foundation, controllers and models with subdirectory support, modular applications |
| Routing | Attribute-based routes, named routes, groups, filters and module routes |
| Views | Twig templates, layouts, includes, framework helpers and custom responses |
| Database | Eloquent ORM, multiple SQL database engines, model-based table definitions and migrations |
| Configuration | YAML configuration, environment-specific overrides, translations and cached initialization |
| Modules | Built-in and custom modules exposed through the same C::Module() interface |
| Authentication | Web authentication, guards, sessions and token-based API authentication |
| Background work | Queue system and scheduled jobs |
| Application services | Events, caching, Redis, HTTP client, mail, validation, logging and file storage |
| Developer tooling | Bob CLI, debug mode, exception handling, Debug Bar and Kint integration |
Charm uses established libraries where they solve a problem well—including Twig, Eloquent, Symfony components, Flysystem, Guzzle and Monolog—while providing a coherent Charm application layer around them.
A controller route can be defined directly where its behavior lives:
namespace App\Controllers;
use Charm\Vivid\C;
use Charm\Vivid\Controller;
use Charm\Vivid\Kernel\Output\View;
use Charm\Vivid\Router\Attributes\Route;
class WelcomeController extends Controller
{
#[Route('GET', '/hello', 'welcome.hello')]
public function hello()
{
$name = C::Request()->get('name', 'World');
return View::make('welcome')->with([
'name' => $name,
]);
}
}The corresponding Twig view can stay equally direct:
{% extends "_base/main.twig" %}
{% block content %}
<h1>Hello {{ name }}</h1>
<p>{{ c('Config').get('user:site_name') }}</p>
{% endblock %}Models are based on Eloquent and can keep their basic table definition close to the model when that is the clearest representation of the application:
namespace App\Models;
use Charm\Vivid\Model;
use Illuminate\Database\Schema\Blueprint;
class Project extends Model
{
protected $table = 'projects';
protected $fillable = [
'name',
'status',
];
public static function getTableStructure(): \Closure
{
return function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('status')->default('active');
$table->timestamps();
};
}
}Traditional migrations remain available when a project benefits from a separate migration history.
- PHP 8.4 or later
- Composer
- required PHP extensions:
- JSON
- Fileinfo
- OpenSSL
- optional, depending on the application:
- MariaDB, MySQL, SQLite, PostgreSQL or SQL Server
- Redis
ext-pcntlfor the built-in cron daemon
Charm is developed for current PHP versions and makes use of modern PHP language features.
The recommended way to create a Charm application is with Bob, the Charm command-line toolkit, and the official Charm Wireframe project template.
curl -fSsL -o bob https://raw.githubusercontent.com/neoground/charm-toolkit/main/bob \
&& chmod +x bob
sudo mv bob /usr/local/bin/bobSee the Charm Toolkit repository for Bob documentation.
bob new AcmePortalBob creates a new application from charm-wireframe and guides you through the initial setup.
Global configuration lives in:
app/Config/
Environment-specific overrides live below:
app/Config/Environments/<Environment>/
The active environment is selected through app/app.env.
Typical configuration files include:
main.yaml
connections.yaml
modules.yaml
bob serveThe Wireframe also includes example configuration for Nginx and Apache deployments.
A conventional Charm project keeps the important parts easy to locate:
app/
├── Config/
├── Controllers/
├── Models/
├── Views/
└── ...
As the project grows, controllers and models can be grouped into subdirectories or application domains can be promoted into dedicated Charm modules. The framework does not require a change of architectural style simply because the codebase becomes larger.
Framework services and loaded application modules share one access pattern:
C::Config();
C::Request();
C::Cache();
C::Queue();
C::Storage();A custom module follows the same model:
C::Billing()->createInvoice($order);This gives applications a small and consistent surface area while keeping modules independently structured and reusable.
Charm:: is available as the long-form alias of C::.
Charm is maintained alongside the systems Neoground builds and operates, and its architecture is shaped by production requirements.
Production deployments can generate the AppStorage cache so stable initialization data is loaded directly rather than rebuilt on each request:
php bob.php appstorage:generateThe framework also provides integrated logging, caching, queues, scheduled tasks, storage abstraction and debug tooling for the operational lifecycle around an application.
Charm 4 is a substantial architectural revision and introduces breaking changes from the 3.x line. Its purpose is to establish a cleaner long-term foundation for Neoground's applications and for external projects building on Charm.
Charm is already used in production, but projects tracking the development line should expect APIs to continue evolving until the 4.0 stable release.
The documentation is being revised alongside Charm 4. Some sections may still describe earlier framework versions or terminology.
Issues, bug reports and focused pull requests are welcome through GitHub.
If you are planning a larger contribution or architectural change, opening an issue first helps keep the work aligned with the framework's direction.
Charm is open source software released under the MIT License.
Charm is developed and maintained by Neoground GmbH, a German technology company working across strategic technology advisory, software systems and digital infrastructure.
We build Charm because we use it: as a durable, understandable foundation for software that has to work beyond the prototype stage.
