Skip to content

Your First Application

This guide walks you through building a simple “Hello World” web application with Marko, introducing key concepts along the way.

Terminal window
composer create-project marko/skeleton hello-marko
cd hello-marko

Create an app/foo directory for your local module. It needs a composer.json to be recognized as a module:

app/foo/composer.json
{
"name": "app/foo",
"type": "marko-module",
"autoload": {
"psr-4": {
"App\\Foo\\": "src/"
}
},
"extra": {
"marko": {
"module": true
}
}
}

Controllers handle HTTP requests. Create one using PHP attributes to define routes:

app/foo/src/Controller/GreetingController.php
<?php
declare(strict_types=1);
namespace App\Foo\Controller;
use Marko\Routing\Attributes\Get;
use Marko\Routing\Http\Response;
class GreetingController
{
#[Get('/hello/{name}')]
public function greet(string $name): Response
{
return new Response(
body: "Hello, {$name}! Welcome to Marko.",
);
}
}
Terminal window
marko up
marko open

If marko isn’t installed yet, run composer global require marko/cli first. See Installation for details.

This opens the site up in your browser. Then, just navigate to http://localhost:8000/hello/World and you’ll see:

Hello, World! Welcome to Marko.

Marko makes JSON responses simple:

app/foo/src/Controller/ApiController.php
<?php
declare(strict_types=1);
namespace App\Foo\Controller;
use Marko\Routing\Attributes\Get;
use Marko\Routing\Http\Response;
class ApiController
{
#[Get('/api/hello/{name}')]
public function greet(string $name): Response
{
return new Response(
body: json_encode(['message' => "Hello, {$name}!", 'framework' => 'Marko']),
headers: ['Content-Type' => 'application/json'],
);
}
}
  • Modules are Composer packages with marko.module: true
  • Routes are defined with PHP attributes (#[Get], #[Post], etc.)
  • Controllers are plain classes — no base class inheritance required
  • Marko auto-discovers modules in app/, modules/, and vendor/