| name | permix-getting-started |
| description | Sets up Permix in an application: install, createPermix schema, setup rules, templates for roles, createRules. Use when adding Permix, defining permission types, role-based access, or permix.setup in a user project. |
| metadata | {"type":"core","library":"permix","library_version":"4.1.2"} |
| requires | [] |
| sources | ["letstri/permix:docs/content/docs/quick-start.mdx","letstri/permix:docs/content/docs/guide/setup.mdx","letstri/permix:docs/content/docs/guide/template.mdx","letstri/permix:docs/content/docs/guide/instance.mdx","letstri/permix:docs/content/docs/guide/events.mdx","letstri/permix:docs/content/docs/migration-v3-to-v4.mdx","letstri/permix:permix/src/core/index.ts"] |
Permix — getting started
Docs: https://permix.letstri.dev/docs/quick-start
Upgrading from v3? Use action tuples, not { action, dataType } — https://permix.letstri.dev/docs/migration-v3-to-v4
Install
pnpm add permix
1. Define the permission schema (once)
Create a shared module (e.g. lib/permix.ts). The generic on createPermix<D>() is the source of truth for all paths and rules.
Nested resources (most common):
import { createPermix } from 'permix'
export const permix = createPermix<{
post: ['create', 'read', 'update', 'delete']
comment: ['create', 'read']
}>()
Flat list (single resource):
export const permix = createPermix<['read', 'write']>()
Deep tree (orgs, workspaces, etc.):
export const permix = createPermix<{
workspace: {
billing: ['view', 'update']
member: ['invite', 'remove']
}
}>()
Every action you declare in D must appear in every setup() call (use false to deny).
2. Assign rules with setup
permix.setup({
post: {
create: true,
read: true,
update: false,
delete: false,
},
comment: {
create: true,
read: true,
},
})
- Static leaf:
boolean
- Depends on resource at check time:
(data) => boolean (see permix skill, references/check.md)
- Call
setup after login, on route change, or when the active user/tenant changes — it replaces previous rules.
3. Optional: initial rules at construction
Skip a separate bootstrap step when rules are known upfront:
export const permix = createPermix<{
post: ['read']
}>({
post: { read: true },
})
permix.isReady()
4. Reusable role presets — template
const admin = permix.template({
post: { create: true, read: true, update: true, delete: true },
})
const member = permix.template({
post: { create: false, read: true, update: true, delete: false },
})
permix.setup(admin())
Dynamic template (parameters):
const forUser = permix.template((user: User) => ({
post: {
update: post => post.authorId === user.id,
},
}))
permix.setup(forUser(currentUser))
5. Typed rules factory — createRules
Use when rules live in another file but must stay type-safe:
import { createPermix, createRules } from 'permix'
const rules = createRules<{
post: ['create']
}>({
post: { create: true },
})
permix.setup(rules)
6. First check
permix.check('post.read')
Before setup, check throws PermixNotReadyError. Unknown paths throw PermixRuleNotDefinedError.
7. React to permission changes (optional)
permix.hook('setup', () => {
})
permix.hookOnce('ready', () => {
})
Docs: https://permix.letstri.dev/docs/guide/events
Checklist for new apps