Logo

Elixir CILicense: MITHex version badgeHexdocs badgeREUSE status

AshTypescript

Automatic TypeScript type generation for Ash resources and actions

Generate type-safe TypeScript clients directly from your Elixir Ash resources, ensuring end-to-end type safety between your backend and frontend. Never write API types manually again.

Breaking Changes

0.16.0

Multi-File Output & Project-Root-Relative Import Paths

AshTypescript now generates multiple output files instead of a single monolithic file. Shared types and Zod schemas are extracted into dedicated files (ash_types.ts and ash_zod.ts) that both RPC and controller code import from.

Additionally, import_into_generated and typed_controller_import_into_generated file paths are now project-root-relative instead of JS-relative import paths. The codegen resolves the correct relative import path for each output file automatically.

What changed:

Migration:

  1. Run mix ash_typescript.codegen — new files will be created alongside the existing output
  2. Update any TypeScript imports that referenced types from ash_rpc.ts to import from ash_types.ts instead
  3. If you use Zod schemas, update imports to use ash_zod.ts
  4. Update import paths from JS-relative to project-root-relative:
    # Before (JS-relative)
    config :ash_typescript,
    import_into_generated: [%{import_name: "RpcHooks", file: "./rpcHooks"}]
    
    # After (project-root-relative)
    config :ash_typescript,
    import_into_generated: [%{import_name: "RpcHooks", file: "assets/js/rpcHooks.ts"}]

No changes are needed if you only import the RPC functions themselves (e.g., import { listTodos } from './ash_rpc').

Compile-Time Verification of public? Actions

Actions and relationship read actions referenced in typescript_rpc blocks are now verified to be public? true at compile time. Previously, non-public actions would silently generate types but fail at runtime. If you see new compile errors like "action :foo is not public?", set public? true on the action or remove it from the typescript_rpc block.

Features

Quick Start

Get up and running in under 5 minutes:

# Basic installation
mix igniter.install ash_typescript

# Full-stack Phoenix + React setup
mix igniter.install ash_typescript --framework react

1. Add Resource Extension

defmodule MyApp.Todo do
  use Ash.Resource,
    domain: MyApp.Domain,
    extensions: [AshTypescript.Resource]

  typescript do
    type_name "Todo"
  end

  attributes do
    uuid_primary_key :id
    attribute :title, :string, allow_nil?: false
    attribute :completed, :boolean, default: false
  end
end

2. Configure Domain

defmodule MyApp.Domain do
  use Ash.Domain, extensions: [AshTypescript.Rpc]

  typescript_rpc do
    resource MyApp.Todo do
      rpc_action :list_todos, :read
      rpc_action :create_todo, :create
      rpc_action :get_todo, :get
    end
  end
end

3. Generate Types & Use

mix ash.codegen --dev
import { listTodos, createTodo } from './ash_rpc';

// Fully type-safe API calls
const todos = await listTodos({
  fields: ["id", "title", "completed"],
  filter: { completed: false }
});

const newTodo = await createTodo({
  fields: ["id", "title", { user: ["name", "email"] }],
  input: { title: "Learn AshTypescript", priority: "high" }
});

That’s it! Your TypeScript frontend now has compile-time type safety for your Elixir backend.

For complete setup instructions, see the Installation Guide.

Documentation

Getting Started

Guides

Features

Advanced

Reference

Core Concepts

AshTypescript bridges the gap between Elixir and TypeScript by automatically generating type-safe client code:

  1. Resource Definition - Define Ash resources with attributes, relationships, and actions
  2. RPC Configuration - Expose specific actions through your domain’s RPC configuration
  3. Type Generation - Run mix ash.codegen to generate TypeScript types and RPC functions
  4. Frontend Integration - Import and use fully type-safe client functions in your TypeScript code

Type Safety Benefits

Example Repository

Check out the AshTypescript Demo by Christian Alexander featuring:

Requirements

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes with tests
  4. Ensure all tests pass (mix test)
  5. Run code formatter (mix format)
  6. Commit your changes (git commit -m 'Add amazing feature')
  7. Push to the branch (git push origin feature/amazing-feature)
  8. Open a Pull Request

Please ensure:

License

This project is licensed under the MIT License - see the LICENSES/MIT.txt file for details.

Support