Zodra

Type-safe from Rails to TypeScript

Define your API once in Rails. Get TypeScript types, Zod schemas, and a typed client automatically. Zero drift, zero surprises.

app/types/user.rb
Zodra.type :user do  uuid :id  string :name, min: 1  string :email  integer :age, min: 0  timestampsend

How it works

Three simple steps to type-safe bliss

1

Define in Ruby

Use the Zodra DSL to define types, contracts, and API routes.

# Define types in RubyZodra.type :post do  uuid :id  string :title, min: 1  string :body  boolean :published, default: false  timestampsend
2

Zodra Generates

TypeScript types, Zod schemas, and a typed client from your Ruby definitions.

// Auto-generated by Zodraimport { z } from 'zod'export const PostSchema = z.object({  id: z.uuid(),  title: z.string().min(1),  body: z.string(),  published: z.boolean().default(false),  created_at: z.iso.datetime(),  updated_at: z.iso.datetime(),})
3

Use in Frontend

Import generated schemas with full TypeScript inference and runtime validation.

// Use in your frontendimport { createApiClient } from '@zodra/client'import { contracts } from './zodra/contracts'const api = createApiClient({  baseUrl: '/api/v1',  contracts,})const { data } = await api.posts.create({  title: "Hello World",  body: "My first post",})

Everything you need

Type safety across the stack, without the hassle

Contract-based validation

Define params and response schemas per action. Validate requests on the backend with generated parsers.

Auto-generated Zod schemas

Your Ruby type definitions automatically generate Zod schemas and TypeScript interfaces. No manual sync.

Full TypeScript inference

Get complete type inference from your schemas. Your IDE knows exactly what shape your data takes.

Standalone type DSL

Types are defined independently from models. One type, one file, reusable across API versions.

Full API framework

Types, contracts, routing, serialization, error handling — everything you need for a Rails API.

Single source of truth

One definition in Ruby powers backend validation, frontend types, and API documentation.

See it in action

From Ruby type to type-safe frontend in seconds

app/types/product.rb
Zodra.type :product do  uuid :id  string :name, min: 1, max: 255  string? :description  decimal :price, min: 0  string :currency, enum: %w[USD EUR GBP]  boolean :in_stock, default: true  array :tags, of: :string  timestampsend

Get started in minutes

Two packages, one unified type system

Backend

Ruby Gem

gem "zodra"

Add to your Gemfile and run bundle install

Frontend

NPM Package

npm install @zodra/client

Or use pnpm / yarn