Getting started
Affordant is an affordance-first hypermedia (HATEOAS) client. The server tells your frontend which actions are available; your UI renders off that, instead of re-deriving authorization rules client-side.
Install
sh
npm install affordantThe core has zero dependencies and runs anywhere fetch exists: browsers, Node ≥ 18, Deno, Bun, edge workers.
The three questions
Every interaction comes down to three calls:
- What is the server offering me? →
can(resource, rel) - Where / how? →
actionFor(resource, rel) - Do it. →
follow(action, init)
ts
import { can, actionFor, follow, type HateoasResource } from 'affordant'
type Order = { id: string; total: number; status: string }
const order: HateoasResource<Order> = await fetch('/orders/8f3a2c').then(r => r.json())
if (can(order, 'cancel')) {
await follow(actionFor(order, 'cancel')!, {
token: () => localStorage.getItem('token'), // lazy getter, read at request time
body: { reason: 'changed my mind' }, // JSON-encoded per the action's `accepts`
})
}can and actionFor are null-safe: pass a resource that is null, undefined, or missing _actions and you get false / null rather than a thrown error. That makes them safe to call while data is still loading.
What you get out of it
- Authorization lives in one place — the server. The presence of the
cancellink is the permission. The frontend never re-implements "can this user cancel this order?". - No hardcoded URLs or verbs. The
hrefandmethodcome from the response. Rename a route on the server and every client follows along. - The button tracks reality. When the server stops offering an action,
can()returnsfalseand the control disappears — with no frontend deploy.
More than the client
affordant is the client, but it is one of a small family sharing a single wire contract:
@affordant/serverbuilds the envelope on the backend — the mirror ofcan().@affordant/expressis a thin Express adapter for it.@affordant/reactwraps the calls as hooks.
See the packages for the whole map, or just keep using the vanilla calls above — they work everywhere.
Next steps
- Understand why REST level 3 is worth reaching, and what it changes for your frontend.
- Tour the packages and how they fit together.
- Understand the wire contract the server emits.
- See framework usage for React, Vue, Svelte, and vanilla.
- Read the full API reference.