AI Skills
How to use PraxisJS AI skills — docs-first development through the MCP server, no duplicated code, the project's folder structure, a versioned project memory and one-time project config for Claude Code and Codex.
AI Skills
PraxisJS ships AI skills that give Claude Code and Codex a structured way to work on your project — looking every API up in the live documentation, reusing what the framework and your project already have, keeping files where your project keeps them, and recording what they build in a project memory the next session reads.
Installing a skill
New project
Select an integration during scaffolding:
npm create praxisjs@latestAt the "Add an AI integration?" step, choose Claude Code or Codex. The CLI ends with a prompt to paste into the agent: it starts the project setup (docs through the MCP server, the project memory, your folder structure and conventions).
Existing project
Run the ai add command at the project root:
npx praxisjs ai addIt ends with a prompt that asks the agent to map the project into its memory. praxisjs ai sync prints the same prompt when it adds the MCP server to a project that didn't have it, and praxisjs add kosmesis prints it when an AI integration is installed.
Setup prompts
Both prompts are in the Quick Start, ready to copy: one starts the setup of a new project (the first session below), the other maps an existing project into the memory with the praxisjs-memory-bootstrap skill.
First session
The first time the agent works in the project, the praxisjs skill runs its session start checklist before your task:
-
MCP server. The agent client starts the
praxisjsserver from the project config (.mcp.jsonfor Claude Code,.codex/config.tomlfor Codex). Claude Code asks you to approve it the first time; check it with/mcp. If thepraxisjs_*tools are missing, the skill stops and walks you through connecting the server (references/mcp.md) instead of guessing APIs. -
praxisjs_inspect_project. Versions, folder layout, pages, components, stores, routes, UI libraries, and whether the project memory exists. -
Questions, in one message. Without a
.praxisjs-ai.json, the five preference questions. When the project memory is not set up, a sixth one, with a suggested answer from whatpraxisjs_inspect_projectfound:6. Is this project still the empty scaffold, or should I map the existing code into the project memory now? (scaffold / map)The answers go into
.praxisjs-ai.json(the sixth asmemory), so they are never asked again. A project that already has the config but no memory gets the sixth question alone. -
Project memory.
scaffold:praxisjs_memory_initonly, which records the folder structure and UI library conventions, without a full analysis; the memory then grows as the agent adds code, and you can map the project later with the map prompt.map: thepraxisjs-memory-bootstrapskill analyzes the project and records it (see Project memory). The agent never starts a full mapping you didn't ask for. -
Your task.
praxisjs_memory_searchfor what applies, the docs pages for the APIs it needs, then the work.
Later sessions read .praxisjs-ai.json and the memory silently and go straight to step 5.
Removing a skill
Run the ai remove command at the project root and pick the integration to uninstall:
npx praxisjs ai removeThis deletes the PraxisJS skills and removes the praxisjs MCP server from the project configuration (other servers and settings stay). It leaves CLAUDE.md/AGENTS.md, .praxisjs-ai.json and .praxis/ alone — those hold project context and preferences that aren't owned exclusively by the integration.
What gets installed
| Integration | Skills | MCP server config | Project memory file |
|---|---|---|---|
| Claude Code | .claude/skills/praxisjs/ + .claude/skills/praxisjs-*/ | .mcp.json, approved in .claude/settings.json | CLAUDE.md |
| Codex | .agents/skills/praxisjs/ + .agents/skills/praxisjs-*/ | .codex/config.toml (trusted projects) | AGENTS.md |
The skills need the MCP server (@praxisjs/mcp): it gives them the docs, your project's structure and the project memory. ai add configures it for both agents; Claude Code asks you to approve it the first time (check with /mcp). For other clients, see the MCP Server page.
The skills
praxisjs is the main skill, loaded for any PraxisJS work. The others are workflows it hands over to:
| Skill | Use |
|---|---|
praxisjs-component | Create or change a component or page: reuse check, type choice, reactive JSX, styles, test, memory entry |
praxisjs-decorator | Build a custom decorator with the current builders (setup form), test it, record it |
praxisjs-composable | Build a Composable attached with @Compose |
praxisjs-store | Shared state with @praxisjs/store, services with @praxisjs/di, store plugins |
praxisjs-testing | Vitest setup with decoratorLoweringPlugin(), what to test for each kind of code, coverage |
praxisjs-performance | Measure with the devtools profiler and @Trace, then fix with For/Index, @Selector, @Lazy, VirtualList |
praxisjs-upgrade | praxisjs upgrade, praxisjs doctor, changelogs and migrations of removed APIs |
praxisjs-memory | Query and maintain the project memory |
praxisjs-memory-bootstrap | First full analysis of the project into the memory, as parallel passes (subagents when the agent has them) |
praxisjs-ui | Use Morphos primitives and Kosmesis components: find, add with the kosmesis CLI, wrap, style, update |
praxisjs-ai-setup | Update an older project's skills, MCP configuration and memory format |
The rules
Every skill follows the same rules:
- Docs before code — every PraxisJS API is looked up through the MCP server (
praxisjs_search_docs,praxisjs_get_page,praxisjs_api_reference) before it is used; the website is only a fallback while the server isn't connected. - MCP connected — when the server's tools are missing, the skill helps you connect it before writing PraxisJS code.
- Reuse, don't duplicate — before creating a component, composable, store, service, decorator or helper,
praxisjs_memory_check_duplicatesearches PraxisJS itself, the project memory and your code. - UI from Morphos and Kosmesis first — before building a UI piece, the skill checks your installed Kosmesis components, the Kosmesis registry and the Morphos primitives; Kosmesis components are added with the
kosmesisCLI and updated withkosmesis outdated/kosmesis update, Morphos primitives are wrapped, never edited innode_modules. - Extend PraxisJS its own way — custom behavior goes through the Extending PraxisJS APIs: the decorator builders (
setupform),Composable, store plugins, devtools plugins. - Never the
accessorkeyword — PraxisJS decorators work on plain fields. - Keep the structure — files go where the project keeps that kind of file (
praxisjs_scaffold); misplaced code the task touches is moved, with your consent for larger moves. See Project structure. - Project memory through the MCP only —
.praxis/is read and written only with thepraxisjs_memory_*tools. - Validate —
praxisjs_validate_fileruns on every file the assistant creates or changes. - No workarounds — if the idiomatic path isn't clear, the skill reads the docs page rather than improvising.
Project config (.praxisjs-ai.json)
On first use the skill asks five questions in a single message (six when the project memory is not set up, see First session) and writes .praxisjs-ai.json at the project root. Every subsequent session reads this file silently — the AI never asks the same questions again.
{
"version": 1,
"tests": true, // generate test files for every new component
"codeLocale": "en", // language for identifiers, comments, variable names
"uiLocale": "pt-BR", // language for user-facing strings in templates
"i18n": false, // set up internationalization support
"css": "tailwind", // praxisjs-css | plain | modules | tailwind | unocss | none
"memory": "scaffold" // how .praxis/ was set up: scaffold (no analysis) | map; only when it was missing
}To update a preference after init, edit .praxisjs-ai.json directly or ask the AI to update it.
Project memory
Two places hold what a new session needs to know:
CLAUDE.md / AGENTS.md | .praxis/ | |
|---|---|---|
| Holds | stack, entry points, constraints, a pointer to .praxis/ | reusable components and utilities, business rules, architecture decisions, conventions, glossary |
| Changed by | the assistant, directly | the assistant, only through the MCP server's praxisjs_memory_* tools |
The skill creates the memory file when missing and updates it when the stack or constraints change. Minimal structure (Claude Code example):
# My App
## Stack
- PraxisJS + @praxisjs/core, @praxisjs/decorators, @praxisjs/runtime, @praxisjs/jsx
- Build: Vite 7 + @praxisjs/vite-plugin
- Routing: @praxisjs/router
- State: @praxisjs/store
## Architecture
SPA. Entry: src/main.tsx. Pages in src/pages/, components in src/components/.
## Project memory
Reusable code, business rules, decisions and conventions are in `.praxis/`, read and changed only
through the PraxisJS MCP server (`praxisjs_memory_*` tools).
## Known constraints
JWT stored in memory only. Targets Chrome 100+..praxis/ is set up on the first session (commit it). For a project that is still the empty scaffold, praxisjs_memory_init creates it with the conventions only. To map a project with code, the praxisjs-memory-bootstrap skill runs when you answer map or ask for it: praxisjs_memory_bootstrap_plan splits a full analysis of the project into eight focused passes — UI components, utilities and stores, routes and pages, business rules, architecture, conventions, dependencies and UI libraries, tests and tooling — that run in parallel when the agent supports subagents and one after another otherwise. Each pass writes only through praxisjs_memory_upsert (dry run first), links every entry to its source files and reports what it couldn't infer, such as business rules, as questions for you. Re-running it updates entries instead of duplicating them and asks before rewriting text people wrote. The memory is then kept current as the assistant adds, changes, moves or removes reusable code and as rules and decisions come up. Its format, tools and safety guarantees are described on the MCP Server page.
The skill will not proceed with any task until the project memory file exists. If it is missing at session start, the skill creates it before writing any code.
Project structure
The skills follow the structure your project already has, as recorded in conventions/project-structure. Two layouts are shown as examples — the skills only suggest one for a new project or when you ask to reorganize:
by kind (create-praxisjs templates) feature slices
src/ src/
app.tsx, main.tsx app/ bootstrap, router, global providers
pages/ features/
components/ (components/ui/ Kosmesis) cart/
stores/ composables/ services/ components/ stores/ composables/ services/
decorators/ utils/ styles/ routes.ts index.ts (public API) __tests__/
__tests__/ shared/
ui/ (Kosmesis components, Morphos wrappers)
lib/ config/ types/In a feature-slice project, features import each other only through their index.ts, shared/ never imports from features/, and tests and styles stay with their feature; praxisjs_validate_file flags imports that cross these lines and praxisjs_scaffold places new files in the right feature (or in shared/).
Updating an existing project
Projects set up by an earlier praxisjs or create-praxisjs move to the current setup with:
npx praxisjs ai sync --dry-run
npx praxisjs ai syncai sync updates every installed integration in place: it adds the new skills, replaces skill files you never changed, removes files the current version no longer ships, and rewrites the MCP server configuration (moving an old entry out of .claude/settings.json, where Claude Code never read it). Files you edited are never overwritten silently: it shows the diff and asks, and without a terminal (CI) it keeps them. It recognizes installs from before it existed by the hashes of every file earlier releases shipped, and from now on records what it installed in .praxisjs-ai.lock.json (commit it). It is safe to run again. praxisjs doctor reports an outdated setup, and praxisjs upgrade offers to sync it after upgrading packages. See ai sync.
Then ask your agent to update the rest — the praxisjs-ai-setup skill walks it through it: a project without .praxis/ gets the memory bootstrap, and a .praxis/ in an older format is migrated with praxisjs_memory_migrate (dry run first, then an atomic swap; see Format versions).
How it uses the MCP server
| Moment | Tools |
|---|---|
| Session start | praxisjs_inspect_project (versions, code, layout, memory status), praxisjs_memory_search for the task |
| Before writing code | praxisjs_search_docs → praxisjs_get_page, praxisjs_api_reference for each API |
| Before creating something reusable | praxisjs_memory_check_duplicate, then praxisjs_scaffold for the path and starter code |
| After writing | praxisjs_validate_file, then praxisjs_memory_add / praxisjs_memory_update |
| Building a UI piece | praxisjs_ui_components, the Morphos/Kosmesis docs (library on the docs tools) |
| Installing a package | praxisjs_get_install_command (no version numbers) |
| Code moved or memory out of date | praxisjs_memory_map |
The full tool list is on the MCP Server page.
Example prompts
These are realistic prompts you can use directly. The skill ensures docs are fetched and conventions are followed before any code is written.
Starting a new project
Start with the setup prompt the CLI prints. Then, for example:
I just scaffolded a PraxisJS project with the router template. Create CLAUDE.md
with the current stack and architecture, then show me the entry point setup.Set up a PraxisJS todo app from scratch — stateful component, add/complete/delete
tasks, filter by status. Create CLAUDE.md first, then fetch the relevant docs
before writing any components.Creating components
Create a UserCard component that receives a user object as a prop and displays
name, avatar, and role. It's stateless — no internal state needed.I need a SearchInput component with debounced input (300ms) that emits a search
event to the parent. Check the decorators/timing docs before implementing.Async data
Add a UserProfile component that fetches /api/users/:id on mount, shows a
skeleton while loading, the profile on success, and a retry button on error.
The userId comes in as a prop.Our ProductList currently fetches on mount. Refetch automatically whenever the
categoryId signal changes. Check the async-data docs first.State management
Add a CartStore to manage items, quantities, and total. Inject it into the
Header and ProductCard components. Update CLAUDE.md with the store pattern.We need authentication state shared across the app — logged-in user, JWT token,
and a hasRole() helper. What's the right approach with PraxisJS store and DI?Routing
Set up client-side routing with three pages: Home, Dashboard (requires auth),
and Profile. Redirect unauthenticated users to /login using a beforeEnter guard.Add a /products/:id route that lazy-loads the ProductDetail component and
reads the id from route params. Fetch the router docs before implementing.Reuse and project memory
Analyze this project and set up the project memory: components, stores, business rules,
architecture and conventions. Use subagents for the passes.Add a settings dialog. Use our Kosmesis components if we have them, otherwise add
the right one from the registry.Before you build a date range picker, check whether we or PraxisJS already have one.Our checkout rule is that a cart holds at most 20 items. Record it and enforce it in CartStore.Refactoring and debugging
This computed value is updating too often — it re-derives even when unrelated
signals change. Read the reactivity docs and explain why, then fix it.Extract the authentication logic from UserPage into a reusable composable.
Check the custom-composables docs for the right pattern.The product list is slow when it has 5,000 rows. Profile it and fix it.Our helpers are scattered across components/ and lib/. Propose where they belong
according to the project structure, then move them.Adding packages
Add @praxisjs/motion to the project and animate the sidebar width when it
toggles open and closed. Install the package first, then fetch the motion docs.The skill always fetches live docs before implementing — you don't need to include docs URLs or decorator option details in your prompt. Describe the intent; the skill handles the lookup.
See also
The skill itself tells you to run praxisjs doctor when something seems misconfigured (including a missing MCP server configuration), and praxisjs upgrade to update @praxisjs/* dependencies. Full reference for both, plus ai add / ai remove, in the praxisjs CLI docs.