Skip to content

marko/skeleton

The official application template for starting new Marko Framework projects. This is a composer create-project template that scaffolds a ready-to-use project structure with the entry point, directory layout, environment config, and dev tooling pre-configured.

Terminal window
composer create-project marko/skeleton my-app
cd my-app
my-app/
├── app/ # Your application modules
├── config/ # Root configuration overrides
├── modules/ # Third-party modules
├── public/
│ └── index.php # Web entry point
├── storage/ # Logs, cache, sessions
├── tests/
├── .env.example # Environment variable template
└── composer.json

The public/index.php bootstraps the application:

<?php
declare(strict_types=1);
require __DIR__ . '/../vendor/autoload.php';
use Marko\Core\Application;
$app = Application::boot(dirname(__DIR__));
$app->handleRequest();

Application::boot() discovers modules, registers bindings, and builds the DI container. handleRequest() routes the incoming HTTP request to the matched controller.

  1. Copy the environment template:
Terminal window
cp .env.example .env
  1. Start the dev server:
Terminal window
marko up
  1. Visit http://localhost:8000
PackageDescription
marko/frameworkMetapackage bundling core, routing, CLI, errors, config, hashing, validation
marko/envEnvironment variable loading (read in config files with Env)
marko/logLoggerInterface and the shared logger (also required by marko/queue)
marko/log-filefile log handler: writes rotated files to storage/logs
marko/log-streamstream log handler: writes to stderr, for containers and PaaS
PackageDescription
marko/devservermarko up / marko down development environment
pestphp/pestTesting framework

The .env.example ships with:

APP_ENV=local
APP_DEBUG=true
APP_URL=http://localhost:8000
# Signed URLs (marko/routing). At least 32 bytes; do not reuse ENCRYPTION_KEY.
# Generate with: php -r 'echo bin2hex(random_bytes(32));'
URL_SIGNING_KEY=
# Logging (marko/log). Both handlers ship: file writes to storage/logs (rotated),
# stream writes to stderr. Containers and PaaS use stream (the platform collects
# stderr); file,stream writes to both.
LOG_HANDLERS=file

URL_SIGNING_KEY is empty on purpose: generate a value per environment before you sign URLs (see Signed URLs). Signing with an empty key throws UrlSigningException.

LOG_HANDLERS=file suits local development: records go to storage/logs. Both handler packages are installed, so switching is a configuration change, not a composer require --- see Logging in Production.

See the Configuration guide for adding database, cache, and other environment variables.

  • PHP 8.5 or higher