• Blog
  • Docs
  • Pricing
  • We’re hiring!
Log inSign up
ianmenethil

ianmenethil

ZenServer

Unlisted
Like
ZenServer
Home
Code
11
.cursor
docs
9
src
10
tasks
tests
.gitignore
.vtignore
README.md
deno.json
H
main.ts
main.tsx
Branches
1
Pull requests
Remixes
History
Environment variables
22
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Sign up now
Code
/
docs
/
OPENAPI_V2_MIGRATION_GUIDE.md
Code
/
docs
/
OPENAPI_V2_MIGRATION_GUIDE.md
Search
7/7/2025
Viewing readonly version of main branch: v313
View latest version
OPENAPI_V2_MIGRATION_GUIDE.md

OpenAPI Loader V2 Migration Guide

Overview

The OpenAPI Loader V2 represents a complete rewrite of the custom OpenAPI implementation using the official @hono/zod-openapi library. This migration dramatically simplifies the codebase and provides better type safety and maintainability.

Key Benefits of V2

πŸš€ Dramatic Code Reduction

  • Before: 1,445 lines of custom OpenAPI implementation
  • After: ~570 lines using the official library
  • Reduction: ~60% less code to maintain

πŸ”§ Better Type Safety

  • Native TypeScript support with @hono/zod-openapi
  • Automatic validation with detailed error messages
  • Type-safe request/response handling

πŸ“š Official Library Support

  • Active maintenance by the Hono team
  • Regular updates and bug fixes
  • Better compatibility with the Hono ecosystem

πŸ—οΈ Cleaner Architecture

  • Route definitions are declarative and easy to understand
  • Separation of concerns between routes and handlers
  • Built-in OpenAPI documentation generation

Migration Comparison

Old Approach (V1)

// Complex custom OpenAPI parsing export class OpenAPILoader { private spec: OpenAPISpec | null = null; private routes: Map<string, RouteConfig> = new Map(); // 1,445 lines of custom implementation async loadSpec(specPath: string): Promise<void> { // Manual JSON parsing // Custom route generation // Complex validation middleware // Manual security scheme parsing } }

New Approach (V2)

// Simple, declarative route definitions const loader = createOpenAPILoaderV2({ title: "ZenServer API", version: "1.0.0", description: "Secure payment and tour booking API" }); // Clean route definition const route = createRouteDefinition('post', '/api/v1/create-nonce', 'createPaymentNonce', { summary: 'Create payment nonce', tags: ['Payment'], security: [{ type: 'rateLimit', required: true }], body: z.object({ amount: z.number().min(0.01), currency: z.string().length(3) }), responses: { 200: { description: 'Payment nonce created successfully', schema: z.object({ nonce: z.string(), expiresAt: z.string().datetime() }) } } });

Side-by-Side Feature Comparison

FeatureV1 (Custom)V2 (@hono/zod-openapi)
Code Size1,445 lines~570 lines
Type SafetyManual typingNative TypeScript
ValidationCustom Zod conversionBuilt-in validation
DocumentationManual spec generationAutomatic OpenAPI docs
MaintenanceHigh (custom code)Low (official library)
Error HandlingCustom error responsesStandardized errors
SecurityManual security parsingBuilt-in security schemes
Route DefinitionComplex configurationDeclarative definitions

Migration Steps

Step 1: Install Dependencies

# Already available in Val Town # @hono/zod-openapi@0.19.9 is imported via esm.sh

Step 2: Replace OpenAPI Loader

// Old way import { OpenAPILoader } from "./openApiLoader.ts"; const loader = new OpenAPILoader(); await loader.loadSpec("./openapi.json"); // New way import { createOpenAPILoaderV2 } from "./openApiLoaderV2.ts"; const loader = createOpenAPILoaderV2({ title: "Your API", version: "1.0.0" });

Step 3: Convert Route Definitions

// Old: Routes defined in JSON spec file // New: Routes defined in TypeScript code const routes = [ createRouteDefinition('get', '/health', 'healthCheck', { summary: 'Health check', responses: { 200: { description: 'Server is healthy', schema: z.object({ status: z.string(), timestamp: z.string().datetime() }) } } }) ]; loader.registerRoutes(routes);

Step 4: Register Handlers

// Same pattern as before const handlers = { healthCheck: async (c) => { return c.json({ status: 'healthy', timestamp: new Date().toISOString() }); } }; loader.registerHandlers(handlers);

Step 5: Get the Hono App

// Export the configured app const app = loader.getApp(); export default app.fetch; // For Val Town

Key Differences

Route Definition

V1: Routes defined in separate JSON file, complex parsing V2: Routes defined in TypeScript with full type safety

Validation

V1: Custom Zod schema conversion with manual middleware V2: Built-in validation with automatic error responses

Documentation

V1: Manual OpenAPI spec generation V2: Automatic OpenAPI documentation at /openapi.json

Security

V1: Complex security scheme parsing from descriptions V2: Built-in security schemes with proper typing

Error Handling

V1: Custom error responses and logging V2: Standardized error responses with proper HTTP status codes

Benefits Realized

1. Development Speed

  • Faster route creation with declarative syntax
  • Immediate feedback with TypeScript types
  • No need to maintain separate JSON specs

2. Type Safety

  • Request/response types are automatically inferred
  • Validation errors are type-safe
  • No runtime type mismatches

3. Maintenance

  • 60% less code to maintain
  • Official library handles edge cases
  • Regular updates from Hono team

4. Documentation

  • Automatic OpenAPI spec generation
  • Always up-to-date documentation
  • Interactive API docs possible

5. Testing

  • Easier to test individual routes
  • Type-safe mocking
  • Better error messages

Migration Checklist

  • Create new OpenAPI Loader V2 instance
  • Convert route definitions from JSON to TypeScript
  • Update handler signatures to use proper Context types
  • Test all endpoints with new validation
  • Verify OpenAPI documentation generation
  • Update middleware to work with new loader
  • Remove old OpenAPI loader and JSON files
  • Update deployment scripts if needed

Compatibility Notes

Val Town Specific

  • Import using https://esm.sh/@hono/zod-openapi@0.19.9
  • Export app.fetch for Val Town compatibility
  • All existing handlers should work with minimal changes

Security Middleware

  • Existing security middleware will continue to work
  • Security schemes are now properly typed
  • Better integration with Hono's middleware system

Next Steps

  1. Phase 1: Create V2 loader alongside V1 for testing
  2. Phase 2: Convert a few endpoints to V2 format
  3. Phase 3: Test thoroughly in development
  4. Phase 4: Migrate all endpoints to V2
  5. Phase 5: Remove V1 loader and cleanup

Conclusion

The OpenAPI Loader V2 represents a significant improvement in:

  • Code maintainability (60% reduction)
  • Type safety (native TypeScript)
  • Developer experience (declarative definitions)
  • Long-term sustainability (official library)

The migration provides immediate benefits and sets up the codebase for future growth with proper typing and modern tooling.

FeaturesVersion controlCode intelligenceCLIMCP
Use cases
TeamsAI agentsSlackGTM
DocsShowcaseTemplatesNewestTrendingAPI examplesNPM packages
PricingNewsletterBlogAboutCareers
We’re hiring!
Brandhi@val.townStatus
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Open Source Pledge
Terms of usePrivacy policyAbuse contact
Β© 2026 Val Town, Inc.