Free & open source — no account required
Free & open source — no account required
This technical guide provides an in-depth analysis of the json to superstruct engine, best practices for implementation, and data security standards.
Superstruct is a TypeScript validation library built around composable, functional validators. Unlike Zod (which builds schemas with a fluent chain API) or Yup (class-based mutations), Superstruct treats schemas as plain data — every schema is just a value you can store, compose, and inspect. It's significantly smaller than Zod (~7kb vs ~57kb) and was a major influence on Zod's design. It's the right choice when bundle size matters or when you prefer the explicit assert/validate/is function model over method chaining.
// Input JSON (API request body)
{
"user_id": "usr_4421",
"email": "user@example.com",
"age": 28,
"role": "editor",
"is_active": true,
"bio": null
}
// Generated Superstruct Schema
import * as s from 'superstruct';
export const rootStruct = s.type({
user_id: s.string(),
email: s.string(),
age: s.number(),
role: s.string(),
is_active: s.boolean(),
bio: s.nullable(s.string()),
});
The generator uses s.type() — this is important to understand:
import * as s from 'superstruct';
// s.object() — strict: rejects objects with extra keys
const StrictUser = s.object({
email: s.string(),
role: s.string(),
});
// s.type() — coercive: allows extra keys (useful for API responses
// where the server may add fields your schema doesn't know about)
const LooseUser = s.type({
email: s.string(),
role: s.string(),
});
const data = { email: 'x@x.com', role: 'admin', extra: 'ignored' };
s.assert(data, StrictUser); // throws — "extra" key not allowed
s.assert(data, LooseUser); // passes — extra keys are fine
import * as s from 'superstruct';
const UserSchema = s.object({
email: s.string(),
age: s.min(s.number(), 13),
role: s.enums(['admin', 'editor', 'viewer'] as const),
});
type User = s.Infer<typeof UserSchema>;
const input = { email: 'dev@example.com', age: 25, role: 'editor' };
// Mode 1: assert — throws StructError on failure, narrows type on success
try {
s.assert(input, UserSchema);
// input is now typed as User
console.log(input.role); // 'editor'
} catch (err) {
if (err instanceof s.StructError) {
console.error(err.path, err.message);
}
}
// Mode 2: validate — returns [error, value] tuple (no throw)
const [err, user] = s.validate(input, UserSchema);
if (err) {
console.error('Validation failed:', err.failures());
} else {
console.log(user.email); // typed as User
}
// Mode 3: is — boolean check, no error details
if (s.is(input, UserSchema)) {
console.log('Valid:', input.role);
}
import * as s from 'superstruct';
// coerce: transform values before validation
const NumberFromString = s.coerce(s.number(), s.string(), (v) => Number(v));
const DateFromString = s.coerce(s.date(), s.string(), (v) => new Date(v));
const EventSchema = s.object({
id: s.string(),
count: NumberFromString, // "42" → 42
created_at: DateFromString, // "2024-01-01" → Date object
});
// mask: strip unknown keys before validation (like Zod's .strip())
const Masked = s.mask(input, s.object({ email: s.string() }));
// Masked only contains { email: '...' }, extra keys removed
// create: coerce + mask in one step
const validated = s.create(rawInput, EventSchema);
.email(), .url()) — write custom refinements.z.infer<> is the gold standard. More built-in validators. The default choice for new TypeScript projects.How do I get the TypeScript type from a Superstruct schema? Use s.Infer<typeof MySchema>: type User = s.Infer<typeof UserSchema>. This derives the TypeScript type from the runtime schema — no duplicate type definitions needed.
Does Superstruct support optional fields? Yes: field: s.optional(s.string()) accepts string | undefined (key can be absent). For nullable: s.nullable(s.string()) accepts string | null. For both: s.optional(s.nullable(s.string())).
How do I add custom validation rules? Use s.refine(): const PositiveNumber = s.refine(s.number(), 'positive', v => v > 0 || 'Must be positive'). The second argument is the error type name; the third returns true on success or an error string on failure.
Is my JSON sent to a server? No. TypeMorph runs entirely in your browser — none of your data leaves your machine.
Is the processing local-only?
Absolutely. TypeMorph operates entirely within your browser's sandbox. We use Web Workers for high-performance computation without ever transmitting your JSON, SQL, or API data to a remote server.
Can I use this for enterprise projects?
Yes. The tool is designed for professional software engineers who require GDPR compliance and data privacy. It is trusted by developers at top-tier startups and financial institutions.