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

@sugardarius/anzen

v2.1.2

Published

Fast, flexible, framework validation agnostic, type‑safe factories for creating route handlers, page and layout Server Component files in Next.js.

Readme

npm size license

Fast, flexible, framework validation agnostic, type‑safe factories for creating route handlers, page and layout Server Component files in Next.js.

  • 🔧 Framework validation agnostic, use a validation library of your choice supporting Standard Schema.
  • 🧠 Focused functionalities, use only features you want.
  • 🧹 Clean and flexible API.
  • 🔒 Type-safe.
  • 🌱 Dependency free. Only Next.js and TypeScript are required as peer dependencies.
  • 🪶 Lightweight. Less than 140kB unpacked.

Install

npm i @sugardarius/anzen

Usage

Route Handlers

import { object, string, number } from 'decoders'
import { createSafeRouteHandler } from '@sugardarius/anzen'
import { auth } from '~/lib/auth'

export const POST = createSafeRouteHandler(
  {
    authorize: async ({ req }) => {
      const session = await auth.getSession(req)
      if (!session) {
        return new Response(null, { status: 401 })
      }

      return { user: session.user }
    },
    body: object({
      foo: string,
      bar: number,
    }),
  },
  async (
    {
      auth, // Auth context is inferred from the authorize function
      body, // Body is inferred from the body validation
    },
    req
  ): Promise<Response> => {
    return Response.json({ user: auth.user, body }, { status: 200 })
  }
)

Page Server Components

import { object, string, number } from 'decoders'
import { unauthorized } from 'next/navigation'
import { createSafePageServerComponent } from '@sugardarius/anzen/server-components'
import { auth } from '~/lib/auth'

export default createSafePageServerComponent(
  {
    authorize: async ({ segments }) => {
      const session = await auth.getSession()
      if (!session) {
        unauthorized()
      }

      return { user: session.user }
    },
    segments: {
      id: string,
    },
    searchParams: {
      page: number,
    },
  },
  async ({
    auth, // Auth context is inferred from the authorize function
    segments, // Segments are inferred from the segments validation
    searchParams, // Search params are inferred from the searchParams validation
  }) => {
    return <div>Hello {auth.user.name}!</div>
  }
)

Layout Server Components

import { z } from 'zod'
import { createSafeLayoutServerComponent } from '@sugardarius/anzen/server-components'
import { auth } from '~/lib/auth'
import { notFound, unauthorized } from 'next/navigation'

export default createSafeLayoutServerComponent(
  {
    segments: {
      accountId: z.string(),
    },
    authorize: async ({ segments }) => {
      const session = await auth.getSession()
      if (!session) {
        unauthorized()
      }

      const hasAccess = await checkAccountAccess(
        session.user.id,
        segments.accountId
      )
      if (!hasAccess) {
        notFound()
      }

      return { user: session.user }
    },
  },
  async ({ auth, segments, children }) => {
    return (
      <div>
        <header>Account: {segments.accountId}</header>
        {children}
      </div>
    )
  }
)

Framework validation agnostic

By design the factories are framework validation agnostic 🌟. When doing your validations you can use whatever you want as framework validation as long as it implements the Standard Schema common interface. You can use your favorite validation library like Zod, Validbot or decoders.

// Route handler example
import { z } from 'zod'
import { object, string, number } from 'decoders'
import { createSafeRouteHandler } from '@sugardarius/anzen'

export const POST = createSafeRouteHandler(
  {
    // `zod` for segments dictionary validation
    segments: { id: z.string() },
    // `decoders` for body object validation
    body: object({
      id: number,
      name: string,
    }),
  },
  async ({ segments, body }) => {
    return Response.json({ segments, body })
  }
)
// Page server component example
import { z } from 'zod'
import { string, number } from 'decoders'
import { createSafePageServerComponent } from '@sugardarius/anzen/server-components'

export default createSafePageServerComponent(
  {
    // `zod` for segments dictionary validation
    segments: { id: z.string() },
    // `decoders` for search params dictionary validation
    searchParams: {
      page: number,
    },
  },
  async ({ segments, searchParams }) => {
    return (
      <div>
        Race {segments.id} - Page {searchParams.page}
      </div>
    )
  }
)

Synchronous validations

The factories do not support async validations. As required by the Standard Schema common interface we should avoid it. In the context of route handlers and server components it's not necessary.

If you define an async validation then the factory will throw an error.

Fair use note

Please note that if you're not using any of the proposed options in the factories it means you're surely don't need them.

// Route handler
// Calling 👇🏻
export const GET = createSafeRouteHandler({}, async () => {
  return new Response(null, { status: 200 })
})

// is equal to declare the route handler this way 👇🏻
export function GET() {
  return new Response(null, { status: 200 })
}
// except `createSafeRouteHandler` will provide by default a native error catching
// and will return a `500` response. That's the only advantage.
// Page server component
// Calling 👇🏻
export default createSafePageServerComponent({}, async () => {
  return <div>Hello</div>
})

// is equal to declare the page server component this way 👇🏻
export default async function Page() {
  return <div>Hello</div>
}
// Layout server component
// Calling 👇🏻
export default createSafeLayoutServerComponent({}, async ({ children }) => {
  return <div>{children}</div>
})

// is equal to declare the layout server component this way 👇🏻
export default async function Layout({
  children,
}: {
  children: React.ReactNode
}) {
  return <div>{children}</div>
}

Feel free to open an issue or a PR if you think a relevant option could be added into the factories 🙂

Requirements

The factories require Next.js v14, v15 or v16 and typescript v5 as peer dependencies.

Contributing

All contributions are welcome! 🙂 Feel free to open an issue if you find a bug or create a pull request if you have a feature request.

Credits

  • Thanks to @t3-oss/env-core for opening the implementation of StandardSchemaDictionary 🙏🏻
  • Thanks to frimousse for opening the release & publish workflow 🙏🏻

License

This project is licensed under the MIT License.