スキーマ駆動開発で便利になりそうなRails To TypeSpecのnpmライブラリを作った
この記事の目次
本記事は【Advent Calendar 2025】の10日目の記事です。
はじめに
ITD2-2-1のH・Tです。マイナビで内製開発しています。
開発現場で作業効率が落ちるタスクがあったので、自分でライブラリを作ったのでその紹介をします。
今後の内製開発でも大いに役立つかなと思ってます。
なにをつくったか
Tatsumaki - Rails to TypeSpec Generator
npmにすでに公開しています。
https://www.npmjs.com/package/@tyranno269/tatsumaki
ライブラリが提供する価値
RailsのDBスキーマからTypeSpecモデルを自動生成するnpmライブラリでスキーマ駆動開発を簡易化できます。
開発モチベーション
マイナビの開発現場では、Rails API + Next.js + zodによる型安全な開発が多いです、ただ以下の課題がありました。
- 手動変換の煩雑さ: Rails schema.rb → TypeSpec → OpenAPI → zodの変換チェーンが手動
- 型同期の遅延: Rails側の変更をフロントエンドに反映するのに時間がかかる
- 型不整合のリスク: 手動変換によるランタイムエラーの発生

OpenAPIからZod生成ではOrvalというライブラリを使用しています。
これによってOpenAPIからシームレスに実装を進められます。一方でバックエンドのRailsからTypeSpecに書き出すのは少々手間をかけていました。ここが自分は煩雑だなと感じてました。これを解決しようと思ったのがライブラリ開発のモチベーションです。
Tatsumakiによる解決
# docsディレクトリで実行
npx @tyranno269/tatsumaki
# → rails.tsp自動生成 → TypeSpec → OpenAPI → orval → zod型定義
機能
Rails schema.rbから自動でTypeSpec生成
Rails enum完全対応 - モデルファイルからenum定義を自動抽出・生成
monorepo対応で柔軟なプロジェクト構造をサポート
型安全性をRailsからフロントエンドまで一貫して確保
Rails互換の単数形化 (company_branches → CompanyBranch)
参考: activesupport/lib/active_support/inflections.rb
想定プロジェクト構造
project/
├── backend/ # Rails API
│ ├── app/models/ # Rails enum定義
│ └── db/
│ └── schema.rb
├── docs/ # TypeSpec (実行場所)
│ └── rails.tsp (生成される)
└── frontend/ # Next.js + zod
Rails Enum
RailsにはModel層にEnum値を定義します。書き方が多様にあります。Schema.rbではintegerですが、APIレスポンスとして返す値はStringのケースが多くあるので対応が必要でした。ただしEnumもi18nで翻訳ファイルを定義するとバックエンドから日本語化して返せますが、フロントエンドメンバーと相談した結果、翻訳はFE側で対応すると良いとの結論になり、純粋にmodelファイルの定義をTypeSpecに出力します。
対応するenum形式
class Company < ApplicationRecord
# ハッシュ形式
enum :company_status, { disabled: 0, enabled: 1, suspended: 9 }
# 配列形式
enum :status, [ :active, :archived ]
# %i記法
enum :priority, %i(low medium high)
# キーワード引数
enum priority: { low: 0, medium: 1, high: 2 }
end
class Book < ApplicationRecord
enum :status, [ :draft, :published, :archived ]
end
生成されるTypeSpec
namespace CompanyEnums {
enum CompanyStatus {
disabled,
enabled,
suspended,
}
enum Status {
active,
archived,
}
}
namespace BookEnums {
enum Status {
draft,
published,
archived,
}
}
model Company {
id: int64;
company_status: CompanyEnums.CompanyStatus; // default: "enabled"
status: CompanyEnums.Status; // default: "active"
created_at: utcDateTime;
updated_at: utcDateTime;
}
model Book {
id: int64;
name: string;
status: BookEnums.Status; // No naming conflict with CompanyEnums.Status
created_at: utcDateTime;
updated_at: utcDateTime;
}
enum機能の特徴
名前空間による衝突回避 - CompanyEnums.Status vs BookEnums.Status
schema.rbとの連携 - テーブル定義があるモデルのみ処理
型置換 - int32フィールドを適切なenum型に変換
全Rails enum構文対応 - ハッシュ、配列、%i記法、キーワード引数
その他にも、a_matsudaさんのStateful_enumといったようにenum定義からブロックでイベントを記述するといったGemもあります。TypeSpecの出力ではブロック部分は回避する工夫もしました。
開発フロー統合
Tatsumakiの設計により、Rails schema.rb + enum → TypeSpec → OpenAPI → zod の完全自動化チェーンを実現し、型安全なフルスタック開発を支援可能になりました。

インストール・使用方法
# 実行(最新版が自動取得される)
npx @tyranno269/tatsumaki
# 既存ファイル上書き
npx @tyranno269/tatsumaki --force
# カスタム出力ファイル
npx @tyranno269/tatsumaki --out models.tsp --force
# 既存ファイルに追記
npx @tyranno269/tatsumaki --append
マイナビでの今後の活用方法
TypeSpecディレクトリ構成次第にはなりますが様々なパターンの開発で応用できうるかとおもいます。
パターン1
project/
├── backend/ # Rails API
│ ├── app/models/ # Rails enum定義
│ └── db/
│ └── schema.rb
├── docs/ # TypeSpec (実行場所)
│ └── rails.tsp (生成される)
└── frontend/ # Next.js + zod
生成されるrails.tspにroutesになるオペレーション情報を記述していくパターン
パターン2
project/
├── backend/ # Rails API
│ ├── app/models/ # Rails enum定義
│ └── db/
│ └── schema.rb
├── docs/ # TypeSpec (実行場所)
│ └── rails.tsp (生成される)
│ └── routes
│ └── admin
│ └── admin.tsp (ex:管理サイトの管理者一覧・詳細など)
│ └── user
│ └── notice.tsp (ex:ユーザーサイトのお知らせ一覧・詳細など)
└── frontend/ # Next.js + zod
生成されるrails.tspにroutesで定義したオペレーションをimportして組み込んでいくパターン
パターン3
project/
├── backend/ # Rails API
│ ├── app/models/ # Rails enum定義
│ └── db/
│ └── schema.rb
├── docs/ # TypeSpec (実行場所)
│ └── rails.tsp (生成される)
│ └── main.tsp (出力の親となるファイル)
│ └── models
│ └── admin.tsp (rail.tspからnamespaceの該当部分をコピペで定義)
│ └── notice.tsp (rail.tspからnamespaceの該当部分をコピペで定義)
│ └── routes
│ └── admin
│ └── admin.tsp (ex:管理サイトの管理者一覧・詳細など)
│ └── user
│ └── notice.tsp (ex:ユーザーサイトのお知らせ一覧・詳細など)
└── frontend/ # Next.js + zod
生成されるrails.tspからコピペで抽出し利用していくパターン
最後に
実際のRailsのプロジェクトで使用される主要機能をカバーできたかなと思っています。よかったら利用してみてください。今回は自分の作業時間を減らしたいモチベーションで生み出したライブラリなので実際のユースケースで対応できていないこともあるかなと思います。要望があればGithub Issueに上げて頂けますと嬉しいです!!
イベント告知

12月23日にイベントを開催します!申し込みはこちらから▼
https://mynaviit.connpass.com/event/376769
※本記事は2025年12月時点の情報です。