Small pieces.
Big builds.
J•Frame is a modular PHP framework: core, components, packages and themes ship as independent Composer packages. Each app takes what it needs and pins it to a compatible version range. It powers a video platform, a CMS, a company management tool, a feed service and a central sign-in.
- PHP 8
- 50+ Composer packages
- SemVer per package
- Docs with ADRs
- continuously developed
Private & not publicly available. J•Frame is a private framework. There is no download and no public installation — it is used exclusively in my own projects on my own servers.
/** * Routes live on the controller — no routing file. * * @Route(path="/hello/") */ class HelloController extends AbstractController { /** @Route(path="{name}") */ public function index(): ResponseInterface { return $this->render('hello.phtml', [ 'name' => $this->getParam('name'), ]); } }
Principles
J•Frame has grown with real applications for years. A few rules have proven themselves along the way.
Packages, not a monolith
Routing, ORM, events, templating … every capability is its own package with its own release cycle. A change to one component never breaks an app pinned to a different range.
Seams over internals
Extensions go through events, registries and configuration — not by patching someone else's code. A new package plugs in without the core having to know about it.
Configuration as code
Config entries are typed PHP objects; secrets come from environment variables
([ENV:…]). The same app runs locally, on staging and in production.
No silent failures
Whatever goes wrong gets logged or reported. A package that swallows an error counts as a bug — even if the page still “works”.
Decisions are written down
Every major fork in the road gets an Architecture Decision Record. Documentation lives with the package, in two languages, in a clear place.
Fast, without magic
Plain PHP templates, discovery caches and OPcache: no build step for PHP, no hidden magic. What the code says is what happens.
One logic, three endpoints
The business logic lives once — in services, entities and permissions. An endpoint is just the way in: whether a person clicks in the browser, a cron job runs or another frontend fetches data, they all use the same logic.
Web
Server-rendered pages with themes, navigation, forms and an admin area that packages extend themselves — from public website to internal tool.
CLI
Custom commands via bin/console, plus a scheduler for recurring jobs:
imports, exports, migrations, cache warm-up, maintenance windows.
API (headless)
JSON endpoints on the same routes and controllers, secured with token or JWT authentication — for custom frontends, apps and other services.
Building blocks
Five layers, each versioned as its own package. An app enables packages in its configuration — controllers and routes are then discovered automatically.
jframe/corejframe-componentjframe-packagejframe-pluginjframe-themeBuilt with J•Frame
Five applications, one foundation. They share the same packages — whatever improves one app reaches the others with their next update.
ViPla
“Your Video Platform”: upload, transcoding and streaming, playlists and collections, ratings and statistics.
vipla.watch →J•CMS
A CMS with themes, menus and a WYSIWYG editor — a public frontend that doesn't require JavaScript, managed through the J•Frame admin area.
jcms.eu →J•CoMa
Companies, customers and projects with roles, a board and tenant separation — the toolbox for everyday agency work.
In internal useJ•Feed
Publishes its own posts like a blog or pulls them from connected sources such as Facebook pages, syncs regularly and serves everything as an Atom feed and a JSON API — ready to embed in other websites.
In use for a clientJ•Acc
User management and sign-in as a service for my own projects: an API with JWT tokens, optionally with two-factor authentication — also for frontends that don't run on J•Frame themselves.
In internal use