rescript-openapi 0.1.0

Generate type-safe ReScript clients from OpenAPI specifications
Documentation

// SPDX-License-Identifier: PMPL-1.0-or-later // SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell

= rescript-openapi :toc: :icons: font

Generate type-safe ReScript clients from OpenAPI specifications.

== Why

OpenAPI is the de facto standard for describing REST APIs. This tool generates:

  • Type definitions - Records, variants, aliases from schemas
  • Runtime validators - Using rescript-schema for safe JSON parsing
  • HTTP clients - Pluggable HTTP layer (fetch by default, bring your own)
  • Operation aliases - Multiple ways to call the same endpoint

== Installation

[source,bash]

cargo install rescript-openapi

Or build from source:

[source,bash]

git clone https://github.com/hyperpolymath/rescript-openapi cd rescript-openapi cargo build --release

== Usage

=== Generate Client

[source,bash]

rescript-openapi generate -i openapi.yaml -o src/api

This generates:

  • ApiTypes.res - All type definitions
  • ApiSchema.res - rescript-schema validators
  • ApiClient.res - HTTP client with fetch

=== Options

[cols="1,2,1"] |=== | Flag | Description | Default

| -i, --input | Path to OpenAPI spec (JSON/YAML) | Required

| -o, --output | Output directory | src/api

| -m, --module | Module name prefix | Api

| --with-schema | Generate rescript-schema validators | true

| --with-client | Generate HTTP client | true

| --unified | Generate single module with types + schemas | false

| --client-mode | Client generation: full, functor-only, none | full

| --variant-mode | Variant style: polymorphic, standard | polymorphic

| -c, --config | Path to rescript-openapi.toml config file | rescript-openapi.toml

| -w, --watch | Watch input file and regenerate on change | false

| --dry-run | Print generated code to stdout | false |===

=== Validate Spec

[source,bash]

rescript-openapi validate -i openapi.yaml

=== Show Info

[source,bash]

rescript-openapi info -i openapi.yaml

== Generated Code

=== Types (ApiTypes.res)

[source,rescript]

/** A user in the system */ type user = { id: string, @as("full_name") fullName: string, email: string, role: option, }

type userRole = [ | #Admin | #User | #Guest ]

=== Schema Validators (ApiSchema.res)

[source,rescript]

module S = RescriptSchema.S

let userSchema: S.t = S.object(s => ({ id: s.field("id", S.string), fullName: s.field("full_name", S.string), email: s.field("email", S.string), role: s.fieldOr("role", S.option(userRoleSchema), None), }: user))

let parseUser = (json: Js.Json.t): user => { S.parseJsonOrThrow(json, userSchema) }

let serializeUser = (value: user): Js.Json.t => { S.reverseConvertToJsonOrThrow(value, userSchema) }

=== HTTP Client (ApiClient.res)

[source,rescript]

// Default client using fetch module Client = Make(FetchClient)

// Usage let config = makeConfig(~baseUrl="https://api.example.com", ())

let result = await Client.getUser(config, ~id="123", ()) switch result { | Ok(user) => Console.log(user.fullName) | Error(err) => Console.error(err.message) }

=== Custom HTTP Backend

[source,rescript]

// Implement the HttpClient signature module AxiosClient: HttpClient = { let request = async (req: httpRequest) => { // Use axios, ky, got, or any HTTP library let response = await Axios.request({ method: req.method->methodToString, url: req.url, headers: req.headers, data: req.body, }) Ok(response.data) } }

// Create client with custom HTTP module Api = Make(AxiosClient)

=== Mock for Testing

[source,rescript]

module MockClient: HttpClient = { let request = async (req) => { // Return mock data Ok(%raw({"id": "123", "full_name": "Test User"})) } }

module TestApi = Make(MockClient)

== ReScript Dependencies

Add to your rescript.json:

[source,json]

{ "bs-dependencies": [ "@rescript/core", "rescript-schema", "@glennsl/rescript-fetch" ] }

Install with npm:

[source,bash]

npm install @rescript/core rescript-schema @glennsl/rescript-fetch

== Roadmap

  • OpenAPI 3.1 support
  • oneOf/anyOf discriminated unions
  • File upload/download
  • Streaming responses
  • WebSocket support
  • GraphQL schema generation

== Part of rescript-full-stack

This tool is part of the link:https://github.com/hyperpolymath/rescript-full-stack[ReScript Full Stack] ecosystem.

== License

PMPL-1.0-or-later