npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

elysia-openapi-codegen

v0.1.4

Published

Generate React Query hooks and fully typed TypeScript interfaces from Elysia OpenAPI specs.

Readme

Elysia OpenAPI Code Generator

Generate fully-typed React Query hooks and TypeScript interfaces from OpenAPI specifications. Perfect for Elysia.js APIs and any OpenAPI 3.x compliant backend.

Features

  • Type-Safe Hooks: Automatically generates React Query hooks with full TypeScript support
  • OpenAPI 3.x Compatible: Works with any valid OpenAPI specification
  • Multiple Input Sources: Fetch specs from URLs or local files
  • Zero Configuration: Simple CLI with sensible defaults
  • React Query Integration: Generates useQuery and useMutation hooks ready to use
  • Flexible Arguments: Supports both flag-based and positional arguments

Installation

Using Bun (Recommended)

bun add -d elysia-openapi-codegen

Using npm

npm install --save-dev elysia-openapi-codegen

Using yarn

yarn add -D elysia-openapi-codegen

Global Installation

# Bun
bun add -g elysia-openapi-codegen

# npm
npm install -g elysia-openapi-codegen

Usage

CLI Flags

elysia-codegen -i <source> -o <output>

Arguments:

  • -i, --input <source> - OpenAPI spec source (URL or file path)
  • -o, --output <output> - Output directory for generated files
  • -h, --help - Show help message

Examples

Using Flag Arguments

# From a URL
elysia-codegen -i https://api.example.com/openapi.json -o ./src/api

# From a local file
elysia-codegen -i ./openapi.json -o ./generated

# Using long-form flags
elysia-codegen --input https://api.example.com/openapi.json --output ./src/api

Using Positional Arguments

# From a URL
elysia-codegen https://api.example.com/openapi.json ./src/api

# From a local file
elysia-codegen ./openapi.json ./generated

With Bun

# Run directly with bun
bun index.ts -i https://api.example.com/openapi.json -o ./src/api

# Or using positional arguments
bun index.ts https://api.example.com/openapi.json ./src/api

Generated Code Usage

The generator creates a single generated.ts file containing all types and hooks.

TypeScript Types

All request/response types are automatically generated:

import type { User, CreateUserBody, GetUsersResponse } from './generated';

// Use types in your components
const user: User = {
  id: 1,
  name: 'John Doe',
  email: '[email protected]'
};

React Query Hooks

Query Hooks (GET requests)

import { useGetUsers, useGetUserById } from './api/generated';

function UsersList() {
  // Simple query with no parameters
  const { data, isLoading, error } = useGetUsers();

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <ul>
      {data?.users.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}

function UserProfile({ userId }: { userId: number }) {
  // Query with parameters
  const { data: user } = useGetUserById(
    { id: userId },
    {
      enabled: !!userId, // React Query options
      staleTime: 5000,
    }
  );

  return <div>{user?.name}</div>;
}

Mutation Hooks (POST, PUT, PATCH, DELETE)

import { useCreateUser, useUpdateUser, useDeleteUser } from './api/generated';
import { useQueryClient } from '@tanstack/react-query';

function CreateUserForm() {
  const queryClient = useQueryClient();

  const { mutate, isPending } = useCreateUser({
    onSuccess: () => {
      // Invalidate and refetch
      queryClient.invalidateQueries({ queryKey: ['getUsers'] });
    },
  });

  const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    const formData = new FormData(e.currentTarget);

    mutate({
      name: formData.get('name') as string,
      email: formData.get('email') as string,
    });
  };

  return (
    <form onSubmit={handleSubmit}>
      <input name="name" required />
      <input name="email" type="email" required />
      <button type="submit" disabled={isPending}>
        {isPending ? 'Creating...' : 'Create User'}
      </button>
    </form>
  );
}

function UserActions({ userId }: { userId: number }) {
  const queryClient = useQueryClient();

  const { mutate: updateUser } = useUpdateUser({
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['getUserById', { id: userId }] });
    },
  });

  const { mutate: deleteUser } = useDeleteUser({
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['getUsers'] });
    },
  });

  return (
    <div>
      <button onClick={() => updateUser({ id: userId, name: 'Updated Name' })}>
        Update
      </button>
      <button onClick={() => deleteUser({ id: userId })}>
        Delete
      </button>
    </div>
  );
}

Advanced Usage

Custom Query Keys

import { useGetUsers } from './api/generated';

function FilteredUsers({ status }: { status: string }) {
  const { data } = useGetUsers(
    { status },
    {
      queryKey: ['users', status], // Custom query key
      staleTime: 60000,
      refetchOnWindowFocus: false,
    }
  );

  return <div>{/* Render users */}</div>;
}

Error Handling

import { useCreateUser } from './api/generated';

function CreateUserForm() {
  const { mutate, error, isError } = useCreateUser({
    onError: (error) => {
      console.error('Failed to create user:', error);
      // Show toast notification, etc.
    },
  });

  return (
    <div>
      {isError && <div className="error">{error.message}</div>}
      {/* Form fields */}
    </div>
  );
}

Optimistic Updates

import { useUpdateUser } from './api/generated';
import { useQueryClient } from '@tanstack/react-query';

function UserEditor({ userId }: { userId: number }) {
  const queryClient = useQueryClient();

  const { mutate } = useUpdateUser({
    onMutate: async (newUser) => {
      // Cancel outgoing refetches
      await queryClient.cancelQueries({ queryKey: ['getUserById', { id: userId }] });

      // Snapshot the previous value
      const previousUser = queryClient.getQueryData(['getUserById', { id: userId }]);

      // Optimistically update
      queryClient.setQueryData(['getUserById', { id: userId }], newUser);

      return { previousUser };
    },
    onError: (err, newUser, context) => {
      // Rollback on error
      queryClient.setQueryData(
        ['getUserById', { id: userId }],
        context?.previousUser
      );
    },
    onSettled: () => {
      queryClient.invalidateQueries({ queryKey: ['getUserById', { id: userId }] });
    },
  });

  return <div>{/* Editor UI */}</div>;
}

Requirements

  • TypeScript: ^5.0.0
  • @tanstack/react-query: ^5.0.0 (peer dependency for generated code)
  • React: ^18.0.0 (peer dependency for generated code)

Project Structure

your-project/
├── src/
│   ├── api/
│   │   └── generated.ts    # Generated by this tool
│   ├── components/
│   │   └── Users.tsx       # Your components using the hooks
│   └── App.tsx
├── openapi.json            # Your OpenAPI spec
└── package.json

Development

Setup

# Install dependencies
bun install

Local Development

# Run directly with Bun during development
bun index.ts -i ./example/openapi.json -o ./output

Building for Production

# Compile TypeScript to JavaScript
npm run build

# Test the compiled version
node dist/index.js --help

The build outputs JavaScript files to the dist/ folder, which is what gets published to npm.

How It Works

  1. Fetches OpenAPI Spec: Reads from a URL or local file
  2. Generates TypeScript Types: Creates interfaces from schema definitions
  3. Creates React Query Hooks: Generates typed hooks for each endpoint
    • GET requests → useQuery hooks
    • POST/PUT/PATCH/DELETE → useMutation hooks
  4. Outputs Single File: All types and hooks in one generated.ts file

Limitations

  • Only supports application/json content types
  • Uses the first server URL as the base URL
  • Assumes standard REST conventions for operations

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT

Related Projects

  • Elysia - Fast and friendly Bun web framework
  • TanStack Query - Powerful data synchronization for React
  • OpenAPI - API specification standard