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

magia-api

v1.7.0

Published

Zero-ceremony typed API client generation

Readme

magia-api

Zero-ceremony typed API client generation for Vite.

Define your APIs once. Get fully typed fetch(), TanStack Query options, and cache keys — all from a single config file. No codegen scripts, no manual types, no boilerplate.

Why Magia?

Every frontend team eventually writes the same glue: fetch wrappers, hand-maintained types, query-key factories, error normalization. Magia replaces all of that with a single config file.

Point it at your OpenAPI or GraphQL schema. The bundler plugin generates types on start. The runtime client gives you typed fetch, TanStack Query integration, interceptors, and error handling — all through one API surface. REST and GraphQL work the same way.

What makes it different from using the underlying tools directly:

  • One config, full stack — You don't wire together a codegen tool, a fetch library, a query-key factory, and an error wrapper. Magia is the entire layer between your API and your components.
  • You never import the internals — The codegen and fetch layers are implementation details. Your code depends on magia-api, not on the tools underneath.
  • It stays out of your way — No runtime overhead, no custom protocols, no vendor lock-in. It generates standard TypeScript and uses standard fetch. Eject anytime by keeping the generated file.
// REST — fully typed from OpenAPI schema
const pet = await magia.petstore.getPetById.fetch({ petId: 1 });

// GraphQL — same API, same DX
const user = await magia.github.GetUser.fetch({ login: "octocat" });

// Safe fetch — no try/catch needed
const { data, error } = await magia.petstore.getPetById.safeFetch({ petId: 1 });

// TanStack Query — standard API, no wrappers
const { data } = useQuery(magia.petstore.getPetById.queryOptions({ petId: 1 }));
const { data } = useQuery(magia.github.GetUser.queryOptions({ login: "octocat" }));

Quick Start

Install

npm install magia-api

1. Create config

npx magia-api init

Or manually create magia.config.ts:

import { defineConfig, tanstackQuery } from "magia-api";

export default defineConfig({
  output: "src/magia.gen.ts",
  apis: {
    petstore: {
      type: "rest",
      schema: "https://petstore3.swagger.io/api/v3/openapi.json",
      plugins: [tanstackQuery()],
    },
  },
});

2. Add Vite plugin

// vite.config.ts
import { magiaApi } from "magia-api/vite";

export default defineConfig({
  plugins: [magiaApi()],
});

3. Create runtime client

// src/lib/magia.ts
import { createMagia } from "magia-api";
import { manifest } from "./magia.gen";

export const magia = createMagia({
  manifest,
  apis: {
    petstore: {
      baseUrl: import.meta.env.VITE_PETSTORE_URL,
    },
  },
});

4. Use it

import { useQuery, useMutation } from "@tanstack/react-query";
import { magia } from "./lib/magia";

// Queries
const { data } = useQuery(magia.petstore.getPetById.queryOptions({ petId: 1 }));

// Mutations
const { mutate } = useMutation(magia.petstore.createPet.mutationOptions());

// Plain fetch
const pet = await magia.petstore.getPetById.fetch({ petId: 1 });

5. Add to .gitignore

src/magia.gen.ts

Features

  • Zero ceremony — No codegen scripts. Bundler plugin generates on start.
  • Any bundler — Vite, Rollup, Webpack, esbuild. Or CLI for scripts and CI.
  • Fully typed — TypeScript types from your OpenAPI/GraphQL schema. No manual types.
  • TanStack QueryqueryOptions(), queryKey(), mutationOptions() via plugin.
  • Flat parameters{ petId: 1, status: "available" } auto-mapped to path/query/body.
  • Incremental — Hash-based skip for unchanged schemas. Fast rebuilds.
  • Tree-shakeable — Per-API manifest exports. Only bundle what you use.
  • Multiple APIs — One config, many APIs. REST and GraphQL.
  • CLImagia-api generate for CI. magia-api validate for checks.
  • Error handlingMagiaError, .safeFetch(), transformError, typed .isError() guard.
  • Interceptors — Per-API onRequest/onResponse hooks with typed context. Inject auth, trace requests.
  • Retry & timeout — Per-API retry and timeout config.

Schema Sources

apis: {
  // URL
  remote: { type: "rest", schema: "https://api.example.com/openapi.json" },
  // Local file
  local: { type: "rest", schema: "./schemas/api.yaml" },
  // Async function
  dynamic: { type: "rest", schema: async () => { /* fetch from anywhere */ } },
  // Shell script
  legacy: { type: "rest", schema: { command: "./scripts/fetch-spec.sh", output: "./spec.json" } },
}

Env var override: MAGIA_PETSTORE_SCHEMA=./local-spec.json

CLI

magia-api generate              # Generate all (skip unchanged)
magia-api generate --force      # Force regenerate all
magia-api generate petstore     # Generate single API
magia-api validate              # Validate config and schemas
magia-api init                  # Scaffold config file

Documentation

Getting Started

Infrastructure

Guides

Reference

Examples

  • Showcase — REST (PokeAPI) + GraphQL (Rick and Morty) with TanStack Query, pagination, safeFetch, interceptors, and Tailwind UI

License

MIT