# Ash Framework

Ash Framework, resources, actions, policies, aggregates, calculations...

- Repository: https://github.com/oliver-kriska/claude-elixir-phoenix (572 stars)
- Category: Engineering
- License: MIT
- Last updated: 2026-10-30
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add oliver-kriska/claude-elixir-phoenix --skill ash-framework -g -a claude-code -y`
Codex: `npx skills add oliver-kriska/claude-elixir-phoenix --skill ash-framework -g -a codex -y`
Cursor: `npx skills add oliver-kriska/claude-elixir-phoenix --skill ash-framework -g -a cursor -y`
Gemini CLI: `npx skills add oliver-kriska/claude-elixir-phoenix --skill ash-framework -g -a gemini-cli -y`
Claude Code plugin marketplace: `/plugin marketplace add oliver-kriska/claude-elixir-phoenix`

## Description

Ash Framework, resources, actions, policies, aggregates, calculations, AshPhoenix.Form, LiveView, migrations. Use when generating resources via mix ash.codegen, editing changes, checks, types, validations, or domain code interfaces.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# Ash Framework Reference

Reference for Ash Framework in Phoenix/LiveView projects.
Ash complements Phoenix/Ecto, LiveView, security, and OTP Iron Laws still apply.
Only data access patterns shift toward Ash actions and domain code interfaces.

## Iron Laws

1. **USE DOMAIN CODE INTERFACES**, Never call `Ash.create/Ash.read` directly in LiveViews or Controllers; use domain code interfaces: `MyApp.Accounts.register_user()` not `Ash.create(User, attrs)`
2. **SET ACTOR/SCOPE AT QUERY PREP, NOT EXECUTION**, Give `actor:` or `scope:` to
   `for_read/for_create/for_action` (prep), NOT to `Ash.read!/Ash.create!` (execution);
   execution-level actor bypasses row-level policy evaluation. If project uses `Ash.Scope`,
   use `scope:` consistently instead of bare `actor:`, do not mix styles
3. **GENERATORS FIRST**, Before writing Ash code manually, run `mix ash.gen.resource` or `mix ash.gen.domain` with `--yes`; check `mix help ash.gen.<task>` for options
4. **CODEGEN AFTER RESOURCE CHANGES**, Always run `mix ash.codegen` after modifying resources; this generates migrations from resource snapshots, never write AshPostgres migrations by hand
5. **ACTIONS OVER FUNCTIONS**, Put business logic in named actions, not domain functions; expose via code interfaces defined on the domain
6. **NEVER EDIT RESOURCE SNAPSHOTS**, `priv/resource_snapshots/` is owned exclusively by `mix ash.codegen`; manual edits corrupt migration tracking
7. **NO DIRECT `Repo.*` IN ASH PROJECTS**, `Repo.all/get/insert` bypass Ash policies and notifications; use domain code interfaces. Any `Repo` call in an Ash project is an escape hatch and must be documented

## Quick Reference

### Domain Code Interface Pattern

```elixir
# Domain definition
defmodule MyApp.Accounts do
  use Ash.Domain

  resources do
    resource MyApp.Accounts.User do
      define :register_user, action: :create, args: [:email, :name]
      define :get_user_by_email, action: :read, get_by: [:email]
    end
  end
end

The rest: https://github.com/oliver-kriska/claude-elixir-phoenix/blob/HEAD/plugins/elixir-phoenix/skills/ash-framework/SKILL.md
