Two Frameworks. One Stack.
Everything you need to build complete web applications, with nothing you don't.
Why Stave?
Zero Bloat
No dependency tree to audit. No node_modules. No build pipeline. The entire framework is a handful of PHP files you can read in an afternoon.
Own Your Stack
Every line is readable. Every decision is traceable. When something breaks, you'll know where to look — because there's nowhere to hide.
Compose, Don't Configure
URL maps to class. File maps to asset. Name maps to component. Convention over configuration means you spend time building, not wiring.
Up and Running in Seconds
See how little it takes to create something real.
A Zero Module
<?php
namespace Zero\Module;
class Hello extends \Zero\Core\Module {
public function index() {
$this->respond($this->viewPath . 'index.php');
}
public function greet($name = 'world') {
$this->data = ['name' => $name];
$this->respond($this->viewPath . 'greet.php');
}
}
- Visit
/helloand the index renders - Visit
/hello/greet/claudeand it greets Claude - Send
Accept: application/jsonand it returns JSON
A ShadowComponent
<template id="my-greeting">
<style>
:host { display: block; }
.greeting { color: var(--accent-primary); }
</style>
<p class="greeting">
Hello, <slot name="name">World</slot>!
</p>
</template>
<script>
class MyGreeting extends ShadowComponent {
static observables = ["name"];
connectedCallback() {
super.connectedCallback();
}
}
customElements.define("my-greeting", MyGreeting);
<\/script>
- Shadow DOM encapsulates styles automatically
- Observable properties sync to slots
- No build step — just include and use