Skip to content

What do I actually need?

NAF is a small core with plugins around it. Nothing is installed that you did not ask for, which is the point — and it means the first question is always which pieces.

These are the starting points people actually have. Find the one closest to yours, run the command, and skip the rest.


One endpoint that answers

A webhook receiver. A health check. A tiny service that takes JSON and gives JSON back.

composer require naf/framework

That is the whole list. Routing, the container, configuration, events, error handling and the request and response objects are all in the core. There is no template engine to switch off and no session being started behind your back.

use function Naf\{json, param, route};

route()->add('POST', '/webhook', function () {
    $payload = param()->all();
    // do the thing
    return json(['ok' => true]);
}, 'webhook');

Read Routing and Requests and responses. You are done.


A small website

Pages people look at, a contact form that posts back, a layout you do not want to repeat.

composer require naf/view naf/form

naf/form brings naf/session with it, because CSRF tokens and remembered input both need somewhere to live. You do not install it separately.

use function Naf\route;
use function Naf\View\render;

route()->add('GET', '/contact', fn() => render('contact'), 'contact');
route()->add('POST', '/contact', [ContactController::class, 'submit'], 'contact.submit');

Read Views and templates and Forms and validation. If the site has more than one language, add naf/i18n.


A JSON API

No templates, no forms, no browser. Clients send a token and expect JSON.

composer require naf/framework

Again just the core. json() is a core helper, and so is abort() for the error cases. You do not want naf/form here: it adds a CSRF check to every POST, PUT and DELETE, which for a token-authenticated API is a check that protects nothing and refuses legitimate requests. If you end up installing it for other reasons, a request with a Bearer token passes anyway — see CSRF protection.

For storage, add one of the two below.


Something to store it in

Two answers, and which one depends on how much structure you want.

composer require naf/database      # PDO, prepared statements, migrations
composer require naf/orm           # entities and repositories — brings naf/database

naf/orm pulls naf/database in, so asking for the ORM is asking for both. Take naf/database alone when you want to write SQL and have it stay SQL; take naf/orm when you would otherwise write the same mapping code by hand.

Read Database or ORM and repositories.


People with accounts

Sign-in, permissions, "this belongs to that user".

composer require naf/auth naf/orm naf/session

naf/auth requires only the core — it can work against anything you write a provider for. But the ordinary case is a user model in a database and a session to stay signed in, which is why the two are suggested alongside it rather than required.

use Naf\Auth\Credentials\PasswordCredentials;
use function Naf\Auth\auth;

if (auth()->authenticate(new PasswordCredentials($email, $password))) {
    // signed in
}

Read Authentication and permissions, and Why auth has this shape if you want the reasoning.


Work that should not happen during the request

Sending mail, resizing images, anything that makes somebody wait for no reason.

composer require naf/queue        # brings naf/cli for the worker command
composer require naf/schedule     # brings naf/queue and naf/cli

naf/queue runs jobs when a worker picks them up. naf/schedule runs them at a time you name, and needs the queue underneath — so asking for the scheduler gives you all three.

Read Queues and workers and Scheduled jobs.


"Sign in with Google"

Let people in with an account they already have, and keep your own user model.

composer require naf/oauth-client

Brings naf/auth and naf/session. The ready-made button and pages also render without naf/view; add it when you want application templates to override the shipped markup.

Read Signing in with a provider.


Being the provider

Other applications sign their users in through you, and your API checks their tokens.

composer require naf/oauth-server

Brings naf/auth, naf/session and naf/form — the consent screen is a form, and it needs CSRF protection like any other.

Read Being the provider. Before you put it in front of anyone, read the concurrency notes in that chapter: the guarantees it makes about simultaneous requests are properties of your database, and SQLite cannot demonstrate them.


A tool for the terminal

No web server at all. Commands you run yourself or from cron.

composer require naf/cli

The core still does the wiring — configuration, the container, events — you just never route an HTTP request through it.

Read Console commands.


Something a language model can call

Exposing part of your application as tools an assistant can use.

composer require naf/mcp

Read MCP tools.


Sending mail

Not a starting point on its own, but the thing everything eventually needs.

composer require naf/mail

Read Sending mail. If it should not block the response, put it behind a queue.


The short version

You are building Install
one endpoint, a webhook, an API naf/framework
a website with pages and forms naf/view naf/form
anything that stores data naf/database or naf/orm
anything with accounts naf/auth naf/orm naf/session
work that happens later naf/queue or naf/schedule
sign-in through Google, GitHub, … naf/oauth-client
your own OAuth provider naf/oauth-server
a command-line tool naf/cli
tools for a language model naf/mcp

Every package's own dependencies come along automatically. The package overview lists what pulls in what.