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 🙏

© 2025 – Pkg Stats / Ryan Hefner

fuapi

v0.0.24

Published

Fusion API between back-end and front-end

Readme

⚡ fuapi - Type-Safe Full-Stack API Framework

fuapi is an API framework designed specifically for TypeScript full-stack development, providing end-to-end type safety

🎯 Core Concepts

  • Unified API Definition - Define once, share between frontend and backend
  • Type Safety - Runtime type validation based on Zod schemas
  • Automatic Inference - Automatic type inference for both client and server, no manual typing needed
  • Standardized Communication - Uses POST method consistently for all data transmission

📝 API Definition Patterns

1. Return-Only API (RetAPI)

export const getHealthApi = defineAPI({
    path: '/health',
    voSchema: z.object({
        status: z.string(),
        uptime: z.number(),
        timestamp: z.string(),
    }),
})

2. Input-Only API (ArgAPI)

export const createUserApi = defineAPI({
    path: '/user/create',
    dtoSchema: z.object({
        name: z.string(),
        email: z.string(),
    }),
})

3. Full Interaction API (StdAPI)

export const getUserApi = defineAPI({
    path: '/user/get',
    dtoSchema: z.object({
        id: z.string(),
    }),
    voSchema: z.object({
        id: z.string(),
        name: z.string(),
        email: z.string(),
    }),
})

4. No Parameters API (PlainAPI)

export const healthCheckApi = defineAPI({
    path: '/health',
})

🖥️ Backend Implementation (implApi)

// packages/server/src/api/user.ts
import {
    getUserApi,
    createUserApi,
    getHealthApi,
} from '@quickest/apis'
import { implApi } from 'fuapi'

export function setupUserApis(app: Express) {
    // Get user information
    implApi({
        express: app,
        api: getUserApi,
        handler: async ({ dto }) => {
            const { id } = dto // All parameters passed through dto
            // Return type automatically inferred as z.output<getUserApi.voSchema>
            return {
                id,
                name: 'John Doe',
                email: '[email protected]',
            }
        },
        onError: (err) => {
            console.error('API Error:', err)
        },
    })

    // Create user
    implApi({
        express: app,
        api: createUserApi,
        handler: async ({ dto }) => {
            // dto type automatically inferred as { name: string; email: string }
            const user = await createUser(dto)
            // No return value (void)
        },
    })

    // Health check (no parameters)
    implApi({
        express: app,
        api: getHealthApi,
        handler: async ({ dto }) => {
            // dto is void, no parameters
            return {
                status: 'OK',
                uptime: process.uptime(),
                timestamp: new Date().toISOString(),
            }
        },
    })
}

🎨 Frontend Usage (clientOfAPI)

// packages/web-app/src/apis/user.ts
import { getUserApi, createUserApi, getHealthApi } from '@quickest/apis'
import { clientOfAPI } from 'fuapi'

// Create clients
export const getUserClient = clientOfAPI({
    api: getUserApi,
    axios: axiosInstance,
    onError: async (err) => {
        console.error('Request failed:', err)
    }
})

export const createUserClient = clientOfAPI({
    api: createUserApi,
    axios: axiosInstance
})

export const getHealthClient = clientOfAPI({
    api: getHealthApi,
    axios: axiosInstance
})

// Usage in React components
function UserProfile({ userId }: { userId: string }) {
    const [user, setUser] = useState(null)
    const [health, setHealth] = useState(null)

    useEffect(() => {
        // All parameters passed through dto
        getUserClient({ id: userId }).then(setUser)

        // No parameter API call
        getHealthClient().then(setHealth)

        // Create user
        createUserClient({
            name: "Jane",
            email: "[email protected]"
        })
    }, [userId])

    return (
        <div>
            <div>User: {user?.name}</div>
            <div>Service Status: {health?.status}</div>
        </div>
    )
}

🔧 Advanced Usage

Parameter Passing

// fuapi doesn't support path parameters, all parameters must be passed through dto
export const getUserPostsApi = defineAPI({
    path: '/user/posts', // Clean path
    dtoSchema: z.object({
        userId: z.string(),
        postId: z.string().optional(),
        limit: z.number().optional(),
    }),
    voSchema: z.object({
        posts: z.array(
            z.object({
                id: z.string(),
                title: z.string(),
            })
        ),
    }),
})

Error Handling

// Backend unified error handling
implApi({
    api: myApi,
    handler: async ({ dto }) => {
        throw new Error('Something went wrong') // Will be caught by onError
    },
    onError: (err) => {
        logger.error(err)
        // Can return custom error response
    },
})

// Frontend error handling
const client = clientOfAPI({
    api: myApi,
    axios: axiosInstance,
    onError: async (err) => {
        // Handle network errors, validation errors, etc.
        showNotification('Request failed')
    },
})

Request Configuration

const client = clientOfAPI({
    api: myApi,
    axios: axiosInstance,
    requestConfig: {
        timeout: 5000,
        headers: { 'Custom-Header': 'value' },
    },
})

🎯 Type Safety Benefits

  1. Compile-time Checking - Frontend and backend errors synchronously when API interface changes
  2. Auto-completion - IDE provides complete parameter and return value suggestions
  3. Runtime Validation - Zod ensures data format correctness
  4. Refactoring Friendly - Frontend and backend update together when renaming fields