SpecStack is a blazing-fast code generation toolkit that transforms OpenAPI 3.0 specs into:
- 🗃️ PostgreSQL schemas and SQL functions
- ⚖️ Fully typed React Query hooks
- 🦍 A simple, powerful intermediate model (SpecIR) for future extensibility
- 🔥 Parse OpenAPI 3.0 specs into strong types
- 💾 Generate DB schemas and CRUD functions
- ⚡ Generate React Query hooks automatically
- 🔹 Auto-index all generated hooks for clean imports
- ⚖️ Full TypeScript safety
- 💡 Built to extend: add zod validators, typed fetchers, SDKs, and more
npm install
npm run dev <path/to/your/openAPI/spec.yaml>
For a quick test, run npm run dev ./tests/petstore.yaml
.
Optional: specify output directory
npm run dev <path/to/your/openAPI/spec.yaml> ./custom_output_dir
Running the command above will create React Query hooks under generated/frontend/src/hooks
.
Import these hooks in your React components (e.g., useGetPetById
) after generation:
import { useGetPetById } from '../generated/frontend/src/hooks';
Stage | What Happens |
---|---|
Parse | OpenAPI spec ➔ Strongly typed SpecIR model |
Transform | SpecIR ➔ DB SQL + React Hooks |
Write | Files saved to generated/ automatically |
Index | Frontend hooks auto-reexported |
flowchart LR
A[OpenAPI Spec<br/>petstore.yaml] --> B[Parse<br/>TypeScript SpecIR]
B --> C[Transform<br/>PostgreSQL Schema]
B --> D[Transform<br/>React Query Hooks]
C --> E[Write<br/>db/schema.sql]
D --> F[Index<br/>frontend/src/hooks/index.ts]
Stage | Sample Output |
---|---|
Parse | ```yaml |
openapi: 3.0.3 | |
paths: | |
/pets: |
get:
operationId: listPets
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
components: schemas: Pet: type: object required: [id, name] properties: id: type: integer name: type: string tag: type: string
| **Transform → SpecIR** | ```ts
const petEntity = specIR.entities.create({
name: 'Pet',
primaryKey: ['id'],
fields: [
{ name: 'id', type: 'integer', nullable: false },
{ name: 'name', type: 'string', nullable: false },
{ name: 'tag', type: 'string', nullable: true },
],
});
``` |
| **Transform → PostgreSQL** | ```sql
CREATE TABLE IF NOT EXISTS pet (
id INTEGER NOT NULL,
name TEXT NOT NULL,
tag TEXT,
PRIMARY KEY (id)
);
``` |
| **Transform → React Hooks** | ```ts
export const useListPets = () =>
useQuery({
queryKey: ['listPets'],
queryFn: () => client.get('/pets'),
});
``` |
| **Write & Index** | Generated SQL is written to `generated/db/schema.sql` and hooks are re-exported from `generated/frontend/src/hooks/index.ts`. |
---
## 📄 Example Outputs
### SQL Table
```sql
CREATE TABLE IF NOT EXISTS Pet (
id INTEGER NOT NULL,
name VARCHAR NOT NULL,
tag VARCHAR,
PRIMARY KEY (id)
);
import { useQuery } from '@tanstack/react-query';
export function useGetPetById(params: { id: number }) {
return useQuery(['getPetById'], async ({ params }) => {
const response = await fetch(`/pets/${encodeURIComponent(params.id)}`);
return response.json();
});
}
- Zod validator generation
- Full CRUD SQL body generation
- OpenAPI mock server from SpecIR
- Swagger UI preview generation
- GitHub Action for auto-regeneration
- Single Source of Truth: Your OpenAPI spec defines database + API + client.
- Type First: No loose strings. Types everywhere.
- Composable: SpecIR can target GraphQL, SDKs, gRPC easily later.
- Minimalism: Only necessary code. No heavy runtimes.
- Inspired by OpenAPI Generator, Prisma, tRPC
- Built lightweight for modern TypeScript apps
MIT License © 2025 SpecStack Project