Packages
ash_typescript
0.6.1
0.17.3
0.17.2
0.17.1
0.17.0
0.16.0
0.15.3
0.15.2
retired
0.15.1
retired
0.15.0
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
retired
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.6
0.11.5
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.2
0.10.1
0.10.0
0.9.1
0.9.0
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.1
0.7.0
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.0
0.4.0
0.3.3
0.3.2
0.3.1
0.2.0
0.1.2
0.1.0
Generate type-safe TypeScript clients directly from your Ash resources and actions, ensuring end-to-end type safety between your backend and frontend.
Current section
Files
Jump to
Current section
Files
documentation/topics/zod-schemas.md
<!--
SPDX-FileCopyrightText: 2025 Torkild G. Kjevik
SPDX-FileCopyrightText: 2025 ash_typescript contributors <https://github.com/ash-project/ash_typescript/graphs.contributors>
SPDX-License-Identifier: MIT
-->
# Zod Runtime Validation
AshTypescript can generate Zod schemas for all your actions, enabling runtime type checking and form validation. Zod is a TypeScript-first schema validation library that provides runtime type safety.
## Configuration
Enable Zod schema generation in your configuration:
```elixir
# config/config.exs
config :ash_typescript,
generate_zod_schemas: true,
zod_import_path: "zod", # or "@hookform/resolvers/zod" etc.
zod_schema_suffix: "ZodSchema"
```
### Configuration Options
- `generate_zod_schemas` - Enable or disable Zod schema generation (default: `false`)
- `zod_import_path` - The import path for the Zod library (default: `"zod"`)
- `zod_schema_suffix` - Suffix for generated schema names (default: `"ZodSchema"`)
## Generated Zod Schemas
For each action, AshTypescript generates validation schemas based on the action's arguments:
```typescript
// Generated schema for creating a todo
export const createTodoZodSchema = z.object({
title: z.string().min(1),
description: z.string().optional(),
priority: z.enum(["low", "medium", "high", "urgent"]).optional(),
dueDate: z.date().optional(),
tags: z.array(z.string()).optional()
});
```
## Using Zod Schemas
### Direct Validation
Use the generated schemas directly for validation:
```typescript
import { createTodoZodSchema } from './ash_rpc';
const input = {
title: "New Todo",
userId: "user-123",
priority: "high"
};
const result = createTodoZodSchema.safeParse(input);
if (result.success) {
console.log("Valid input:", result.data);
} else {
console.error("Validation errors:", result.error.issues);
}
```
### Form Integration
Integrate with popular form libraries:
```typescript
import { createTodoZodSchema } from './ash_rpc';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
function TodoForm() {
const { register, handleSubmit, formState: { errors } } = useForm({
resolver: zodResolver(createTodoZodSchema)
});
const onSubmit = async (data) => {
const result = await createTodo({
fields: ["id", "title"],
input: {
...data,
userId: "user-123" // Add userId (not in form, from auth context)
}
});
if (result.success) {
console.log("Todo created:", result.data);
}
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("title")} />
{errors.title && <span>{errors.title.message}</span>}
{/* ... other form fields ... */}
</form>
);
}
```
## Type Inference
Zod schemas are fully type-safe and can be used for type inference:
```typescript
import { z } from 'zod';
import { createTodoZodSchema } from './ash_rpc';
// Infer TypeScript type from Zod schema
type CreateTodoInput = z.infer<typeof createTodoZodSchema>;
const input: CreateTodoInput = {
title: "New Todo",
priority: "high"
// TypeScript enforces the schema structure
};
```
## Schema Customization
The generated Zod schemas automatically respect Ash attribute constraints (min/max length, allowed values, etc.). When you define constraints in your Ash resources, AshTypescript translates them into the appropriate Zod validators:
```typescript
// Generated Zod schema with constraints
export const createTodoZodSchema = z.object({
title: z.string().min(1).max(100), // Reflects Ash min_length/max_length constraints
priority: z.enum(["low", "medium", "high", "urgent"]).optional() // Reflects Ash one_of constraint
});
```
For more information on defining attribute constraints, see the [Ash attributes documentation](https://hexdocs.pm/ash/Ash.Resource.Dsl.html#attributes).
### Important: Zod Schemas are Complementary
**Zod schemas cannot represent all Ash validations.** Complex validations, action-specific logic, database constraints, and business rules may exist on the server that cannot be expressed in a Zod schema.
**Best Practice**: Always use Zod schemas in combination with server-side validation:
1. **Client-side (Zod)**: Provides instant feedback for basic constraints like required fields, string lengths, and enum values
2. **Server-side (Ash)**: Enforces all validation rules, business logic, and database constraints
This layered approach provides the best user experience while maintaining data integrity.
## See Also
- [Form Validation](form-validation.md) - Learn about server-side validation functions
- [Configuration Reference](../reference/configuration.md) - View all Zod-related configuration options
- [Zod Documentation](https://zod.dev/) - Official Zod documentation