@arex95/phalanx
| Install | |
|---|---|
npm install @arex95/phalanx |
|
| Latest Version: | 6.1.0 |
| Vue: | 3 |
| License: | MIT |
| Last Updated: | Sep 7, 2026 |
| Links: | GitHub · npm |
Phalanx
The headless framework for admin panels.
Everything an admin panel needs below the interface. Define a resource once and get its service, TanStack queries and mutations, and its custom operations — with sessions, realtime, encrypted storage and typed errors already decided.
Headless: it ships no components and no styles, so the interface stays yours.
📖 Documentation · Getting started · Server requirements · Migrating from vue-core
pnpm add @arex95/phalanx
pnpm add vue axios @tanstack/vue-query jwt-decode
Example
import {
RestStd, defineAction, createDomainQueries, createDomainMutations, createModelKeys
} from '@arex95/phalanx';
class UserService extends RestStd {
static resource = 'users';
static suspend = defineAction(
(id: string) => this.customRequest<User>({
method: 'POST',
url: `users/${id}/suspend`
}),
{ permission: 'users.suspend', requiresConfirmation: true, invalidate: ['users'] }
);
}
const userKeys = createModelKeys('admin:user');
export const userQueries = createDomainQueries({ service: UserService, keys: userKeys });
export const userMutations = createDomainMutations({ service: UserService, keys: userKeys });
<script setup lang="ts">
const { data, isPending } = userQueries.getAll({ params: filters });
const { suspend } = userMutations;
</script>
<template>
<button :disabled="!suspend.isAuthorized.value" @click="suspend.mutate(id)">
Suspend
</button>
</template>
suspend is a typed mutation that checks the permission, asks for
confirmation, reports the result and invalidates the list.
What it covers
- Services. One class per resource, eleven inherited methods, custom operations alongside them.
- Composables. TanStack queries and mutations generated from the service, including custom methods with their inferred types.
- Actions. Permission, confirmation, notification and invalidation declared as metadata rather than repeated in each view.
- Session. Access token in memory, refresh token in an
HttpOnlycookie, one refresh in flight with concurrent 401s queued behind it. - Errors.
AuthError,ValidationError,ServerError,NetworkErrorfrom every call, with validation issues normalised across four common API shapes. - Realtime. A reconnection state machine with backoff, a circuit breaker and a token refresh when the stream rejects one. The transport is injected, so it runs over SSE, a WebSocket or anything else.
- Encryption. Browser storage encrypted under a non-extractable key, and hybrid field encryption for data that should only be readable by the server.
- The small things. Idempotency keys, contextual headers, a shared signal for when the API is unreachable.
It ships no components and no styles: the screen stays yours.
Requirements
| Peer dependency | Version |
|---|---|
vue |
>=3.0.0 |
axios |
>=1.15.2 |
@tanstack/vue-query |
>=5.0.0 |
jwt-decode |
^4.0.0 |
ESM only. Node 15+ to build against it.
The refresh cookie is set by your API:
Set-Cookie: refresh_token=…; HttpOnly; Secure; SameSite=None; Path=/auth/refresh
Full list, including the CORS pair for cross-origin setups: Server requirements.
Development
pnpm install
pnpm test # unit tests
pnpm typecheck
pnpm lint
pnpm build
pnpm -C docs dev # documentation site
prepublishOnly runs typecheck, lint, tests and build. The same five steps run
on every push and pull request — see .github/workflows/test.yml.
License
MIT
Related Packages
Auth client for browser apps. Cookies + automatic refresh + React and Vue 3 adap...
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 6.1.0 | >=3.0.0 | MIT | |
| 6.0.0 | >=3.0.0 | MIT |