Type-safe OpenAPI generation and runtime validation for SvelteKit.
Write standard SvelteKit code, get documented APIs for free.
[!WARNING] > 🚧 v0 - Experimental
This plugin is in early development (v0) and not recommended for production use. APIs will most probably change, and there may be undiscovered bugs. Use at your own risk.
Contributions are welcome! If you'd like to help improve this project, please feel free to open issues or submit pull requests.
request.json<Type>() calls.+server.ts files.npm install -D sveltekit-auto-openapi
pnpm install -D sveltekit-auto-openapi
bun install -D sveltekit-auto-openapi
Add the plugin to vite.config.ts to enable schema generation.
import { sveltekit } from "@sveltejs/kit/vite";
import { defineConfig } from "vite";
+ import svelteOpenApi from "sveltekit-auto-openapi/plugin";
export default defineConfig({
plugins: [
sveltekit(),
+ svelteOpenApi(),
],
});
Import and run the function in svelte.config.js to automatically generate types on sync
import adapter from '@sveltejs/adapter-vercel';
// ...imports
+ import { generateAutoOpenApiTypes } from "sveltekit-auto-openapi/sync-helper";
+ generateAutoOpenApiTypes();
/** @type {import('@sveltejs/kit').Config} */
const config = {
// ...sveltekit config
};
export default config;
Expose your documentation at src/routes/api-docs/[slug]/+server.ts.
import ScalarModule from "sveltekit-auto-openapi/scalar-module";
export const { GET, _config } = ScalarModule({
openApiOpts: {
openapi: "3.0.0",
info: { title: "My App API", version: "1.0.0" },
},
});
Thats it! Visit your docs at /api-docs/scalar
Check out the Basic Example to see SvelteKit Auto OpenAPI in action.
View the example source code to learn how it's implemented.
Just write your code. We infer the schema from your generic types.
// src/routes/api/auth/+server.ts
import { error, json } from "@sveltejs/kit";
export async function POST({ request }) {
const { email }: { email: string } = await request.json();
if (email !== "[email protected]") {
error(404, {
message: "User not found",
});
}
return json({ success: true });
}
Export a _config object with validation schemas to enforce runtime validation and generate detailed docs.
import z from "zod";
import type { RouteConfig } from "sveltekit-auto-openapi/types";
export const _config = {
openapiOverride: {
POST: {
summary: "Create user",
description: "Creates a new user with email",
// Validate request body (standard OpenAPI structure)
requestBody: {
// Validate custom properties with $ prefix
$headers: {
schema: z.looseObject({ "x-api-key": z.string() }),
},
content: {
"application/json": {
schema: z.object({ email: z.email() }),
},
},
},
// Validate responses (standard OpenAPI structure)
responses: {
"200": {
description: "Success",
content: {
"application/json": {
schema: z.object({
success: z.literal(true),
}),
},
},
},
"404": {
description: "Success",
content: {
"application/json": {
schema: z.object({
message: z.string(),
}),
},
},
},
},
},
},
} satisfies RouteConfig;
export async function POST({ validated, json, error }) {
const { email } = validated.body;
if (email !== "[email protected]") {
error(404, {
message: "User not found",
});
}
return json({ success: true });
}
Don't want to use StandardShema? You can provide raw JSON Schema objects directly:
import type { RouteConfig } from "sveltekit-auto-openapi/types";
export const _config = {
openapiOverride: {
POST: {
summary: "Create user",
description: "Creates a new user with email",
parameters: [
{
name: "x-api-key",
in: "header",
required: true,
schema: {
type: "string",
},
},
],
requestBody: {
content: {
"application/json": {
schema: {
type: "object",
properties: {
email: {
type: "string",
format: "email",
pattern:
"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
},
},
required: ["email"],
additionalProperties: false,
},
},
},
},
responses: {
"200": {
description: "Success",
content: {
"application/json": {
schema: {
type: "object",
properties: {
success: {
type: "boolean",
const: true,
},
},
required: ["success"],
additionalProperties: false,
},
},
},
},
"404": {
description: "Success",
content: {
"application/json": {
schema: {
type: "object",
properties: {
message: {
type: "string",
},
},
required: ["message"],
additionalProperties: false,
},
},
},
},
},
},
},
} satisfies RouteConfig;
export async function POST({ validated, json, error }) {
const { email } = validated.body;
if (email !== "[email protected]") {
error(404, {
message: "User not found",
});
}
return json({ success: true });
}
For advanced users who need direct access to generated schemas, virtual modules are available:
import openApiPaths from "virtual:sveltekit-auto-openapi/schema-paths";
Note: Most users don't need to import these directly - they're used internally by the plugin.