ionzile/ions
| Install | |
|---|---|
composer require ionzile/ions |
|
| Latest Version: | 4.6.1 |
| PHP: | >=8.3 |
| License: | MIT |
| Last Updated: | Jun 13, 2026 |
| Links: | GitHub · Packagist |
Ions Framework — Starter (ionzile/ions)
A minimal host application for the Ions PHP framework (ionzile/core). This is the published starter — create a new app with one command.
Quick start
composer create-project ionzile/ions my-app
cd my-app
cp .env.example .env
# set APP_KEY in .env (64-char hex):
php -r "echo bin2hex(random_bytes(32)), PHP_EOL;"
# sanity-check the setup (APP_KEY, writable var/, DB, security posture):
php bin/ions doctor
php bin/ions serve # dev server on http://127.0.0.1:8000 (--host/--port)
(serve wraps PHP's built-in server — php -S localhost:8000 -t public
works just as well if you prefer the raw command.)
Open http://localhost:8000 — you should see the welcome page. curl localhost:8000/api/ping returns JSON.
Serving behind nginx or Apache? public/.htaccess ships the Apache rewrite;
for the full nginx/Apache configs, PHP-FPM notes and the deploy checklist see
docs/deploy.md in ionzile/core.
Local HTTP dev: session cookies are
Secureby default (4.1). If you need session/CSRF over plainhttp://localhost, set'cookie_secure' => 'auto'inconfig/session.php.
Where things live
| Path | Purpose |
|---|---|
public/index.php |
Front controller (Kernel::boot() + Kernel::run()) |
bin/ions |
Console (php bin/ions list, make:*, migrate, queue:work, optimize, doctor) |
config/ |
One PHP file per namespace: app.php → config('app.*'), … |
routes/web.php, routes/api.php |
Route definitions (Ions\Bundles\Route) |
app/ |
Application code (App\ PSR-4): models in app/Models, controllers in app/Http/Controllers, API controllers in app/Http/Api, commands in app/Commands, service providers in app/Providers (auto-discovered — no app.providers entry needed; see docs/config.md in ionzile/core) |
database/ |
Standard data layout (4.4+): migrations/, seeders/ (Database\Seeders), factories/ (Database\Factories), schemas/, backups/. The two Database\… sub-namespaces are PSR-4-mapped in composer.json. |
views/ |
Twig templates |
public/uploads, public/lang |
Uploads disk root, translation files |
var/ |
Writable: cache/, logs/, templates/ (compiled Twig) |
Generators: php bin/ions make:command|make:middleware|make:service-provider|make:resource|make:request|make:job|make:event|make:listener|make:test <Name> scaffold the corresponding class into app/ (or tests/ for make:test) — see docs/console.md in ionzile/core.
Frontend assets
The skeleton ships no frontend tooling — pick a scaffold when you need one:
php bin/ions install:vue— Vue 3 + Vite (dev server with HMR, hashed builds inpublic/build/, loaded via thevite()Twig function).php bin/ions install:assets— plain CSS/JS starters inpublic/assets/, linked viaasset()with filemtime cache-busting. No node required.
See docs/assets.md in ionzile/core.
Testing
The skeleton ships runnable test scaffolding: pestphp/pest in require-dev,
a phpunit.xml pointing at tests/, and tests/ExampleTest.php. Run the
suite with vendor/bin/pest (or composer test).
The framework ships a host-app test kit: subclass Ions\Testing\TestCase,
point $basePath at this directory, and drive the full HTTP stack in-process
(no web server). See docs/testing.md in ionzile/core for the full guide.
final class PingTest extends \Ions\Testing\TestCase
{
protected string $basePath = __DIR__ . '/..'; // app root (from tests/)
public function test_ping(): void
{
$this->get('/api/ping')
->assertOk()
->assertJsonPath('data.message', 'pong');
}
}
actingAs($userIdOrUser) issues a real JWT for protected /api routes —
it requires APP_KEY (≥ 32 bytes) in the .env used by your tests.
Test fakes ship with the kit: Queue::fake(), Event::fake(),
Storage::fake() and Mail::fake() swap the real service for a recorder
with assertion helpers (assertDispatched, assertFired, assertStored,
assertSent, …) — see the Fakes section of docs/testing.md.
Production notes
- Set
APP_DEBUG=falseand runphp bin/ions optimize(route + config caches). - CORS is deny-by-default; configure
app.cors.originswhen serving cross-origin traffic. - Review
UPGRADE-4.1.mdinionzile/corefor the 4.1 security defaults this skeleton embraces. - Growing the app?
docs/best-practices.mdinionzile/coreis the opinionated structure guide this layout follows.
Related Packages
Vireo Framework application starter template with Vertical Slice Architecture an...
Modern PHP package skeleton with strict quality rules, PHPStan max level, Pest t...