Install & Compatibility
Where this runs
No compatibility data collected yet for this library.
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
@schema attribute
✓ Add @schema attribute above a type declaration in .res file
✗ Adding @schema to a type alias or record field that is not a top-level type
Applies only to type declarations and type signatures, not expressions.
S.union (generated)
✓ Generated via @schema on variant type; e.g., let ratingSchema = S.union([...])
✗ Manually constructing S.union with wrong order of labels
Always generated by PPX — do not write manually.
PPX binary usage
✓ "ppx-flags": ["sury-ppx/bin"] in rescript.json
✗ Omitting ppx-flags or using wrong path (e.g., "sury-ppx")
Must add both sury and sury-ppx as dependencies; PPX runs during build to generate schema let bindings.
Demonstrates creating a Sury schema from ReScript types using @schema attribute and basic parsing/encoding.
// Install: npm install sury sury-ppx
// Update rescript.json:
{
"bs-dependencies": ["sury"],
"ppx-flags": ["sury-ppx/bin"]
}
// In your .res file:
@schema
type rating =
| @as("G") GeneralAudiences
| @as("PG") ParentalGuidanceSuggested
| @as("PG13") ParentalStronglyCautioned
| @as("R") Restricted
@schema
type film = {
@as("Id")
id: float,
@as("Title")
title: string,
@as("Tags")
tags: @s.default([]) array<string>,
@as("Rating")
rating: rating,
@as("Age")
deprecatedAgeRestriction: @s.meta({deprecated: true}) option<int>,
}
// Generated PPX output (you don't write this):
// let filmSchema = S.object(s => { ... })
// Usage:
let rawData = %raw(`{"Id":1,"Title":"My first film","Rating":"R","Age":17}`)
let film = rawData->S.parseOrThrow(filmSchema)
// Convert back to unknown:
let encoded = film->S.decodeOrThrow(~from=filmSchema, ~to=S.unknown)
// Generate JSON Schema:
let jsonSchema = filmSchema->S.toJSONSchema
Debug
Known issues
breakingsury-ppx 11.0.0-alpha.7 requires sury ^11.0.0-alpha.6 — incompatible with sury 10.x or lower.fixEnsure sury version is ^11.0.0-alpha.6 in package.json.
affects: 11.0.0-alpha.7
deprecatedThe @s.default attribute is used with option types; future versions may change default handling.fixUse @s.default only with type expressions that are not already option; see docs for @s.null + @s.default combo.
affects: >=11.0.0-alpha.7
gotchaMisspelling attribute names (e.g., @schema instead of @schema) may silently fail to generate schema.fixCheck compiler output for missing schema generation; use a linter like rescript-lint to enforce correct attributes.
affects: *
gotchaThe PPX only generates schemas for types with @schema attribute — omitting it results in no schema binding.fixAlways add @schema above the type declaration you want a schema for.
affects: *
Errors
Common errors & fixes
Error: Cannot find module 'sury-ppx/bin'
Missing sury-ppx dependency or incorrect path in ppx-flags.
fixRun `npm install sury-ppx` and ensure rescript.json has "ppx-flags": ["sury-ppx/bin"].
Error: PPX transform failed: unknown attribute @s.typo
Typo in an attribute like @s.default (correct) vs @s.defualt.
fixCheck attribute names against API reference; use @s.default, @s.null, @s.nullable, @s.matches, @s.meta.
Error: Type mismatch; expected S.t<'a> but got something else
Using S.parseOrThrow with a non-schema value (e.g., missing @schema or wrong let binding).
fixEnsure the second argument to S.parseOrThrow is a schema generated by PPX (lowercase starting, e.g., filmSchema, not FilmSchema).
Upgrade
Version history
11.0.0-alpha.7latest on npm
Audit
Dependencies
suryrequiredPeer dependency; provides the core schema types (S.t, S.object, etc.) used by generated code.