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

@mailflix/actions

v0.0.2

Published

Declare website actions and expose Mailflix-compatible OpenAPI endpoints.

Readme

@mailflix/actions

Declare website actions in code and expose them to Mailflix as generated OpenAPI, a discovery manifest, and signed execution endpoints.

Install

npm install @mailflix/actions

For pnpm or Yarn:

pnpm add @mailflix/actions
yarn add @mailflix/actions

Next.js setup

After installing the package in a Next.js App Router project, scaffold the registry file and route handlers:

npx mailflix-actions init --title "Acme Actions"

The CLI creates:

  • mailflix-actions.ts or src/mailflix-actions.ts
  • app/.well-known/mailflix-actions.json/route.ts
  • app/api/mailflix/openapi.json/route.ts
  • app/api/mailflix/actions/[action]/route.ts

Useful options:

npx mailflix-actions init --dir ./apps/web
npx mailflix-actions init --app-dir src/app --registry src/mailflix-actions.ts
npx mailflix-actions init --secret-env MAILFLIX_ACTIONS_SECRET --force

If you are running it before installing the package, use:

npx -p @mailflix/actions mailflix-actions init
import { createMailflixActions } from "@mailflix/actions";

export const mf = createMailflixActions({
  title: "Acme Actions",
  secret: process.env.MAILFLIX_ACTIONS_SECRET,
});

mf.action(
  "add_to_cart",
  {
    title: "Add to cart",
    inputSchema: {
      type: "object",
      properties: {
        variantId: { type: "string" },
        quantity: { type: "integer", minimum: 1, maximum: 10 },
      },
      required: ["variantId", "quantity"],
    },
    confirmation: "soft",
    destructive: false,
  },
  async ({ input, visitor }) => {
    return { accepted: true, input, visitor };
  },
);

Next.js app router

Use explicit route files when you want conventional URLs:

// app/.well-known/mailflix-actions.json/route.ts
import { mf } from "@/mailflix-actions";
export const GET = mf.discovery;
// app/api/mailflix/openapi.json/route.ts
import { mf } from "@/mailflix-actions";
export const GET = mf.openapi;
// app/api/mailflix/actions/[action]/route.ts
import { mf } from "@/mailflix-actions";
export const POST = mf.nextHandlers().execute.POST;

Or mount one catch-all route and let the package route discovery, OpenAPI, and execution by pathname:

// app/[[...mailflix]]/route.ts
import { mf } from "@/mailflix-actions";

const handlers = mf.nextHandlers().catchAll;
export const GET = handlers.GET;
export const POST = handlers.POST;

Fetch runtimes

Any Fetch-compatible runtime can use handle() directly:

export default {
  fetch(request: Request) {
    return mf.handle(request);
  },
};

Discovery

Expose discovery at /.well-known/mailflix-actions.json. The manifest points Mailflix to the generated OpenAPI document and describes signature requirements. When a secret is configured, mf.execute() verifies x-mailflix-timestamp and x-mailflix-signature before running handlers.

Execution requests can also be signed manually with signMailflixBody() for tests or non-Mailflix callers.

Niche starter kits

Starter kits register predictable small-business actions and add Mailflix metadata to the generated OpenAPI via x-mailflix-action. Mailflix uses that metadata for admin grouping, confirmation policy, and richer widget selection.

Only actions with handlers are registered, so you can start with the few capabilities the business actually supports.

import {
  createMailflixActions,
  installRestaurantKit,
} from "@mailflix/actions";

export const mf = createMailflixActions({
  title: "Bistro Actions",
  secret: process.env.MAILFLIX_ACTIONS_SECRET,
});

installRestaurantKit(mf, {
  "restaurant.menu.search": async ({ input }) => {
    return {
      items: await searchMenu(input),
    };
  },
  "restaurant.reservation.availability": async ({ input }) => {
    return {
      slots: await findReservationSlots(input),
    };
  },
});

Available kits:

  • installRestaurantKit: menu search/details, specials, popular items, hours, reservation availability, reservation request.
  • installRentalKit: rental search/details, pricing, availability, viewing booking, quote request.

The root import exports everything for convenience. For larger applications or bundles that prefer narrower imports, kits are also available as subpaths:

import { createMailflixActions } from "@mailflix/actions/runtime";
import { installRestaurantCatalog } from "@mailflix/actions/kits/restaurant";

No API yet: expose a catalog

Small businesses can start with plain structured data. The catalog installers register handlers for search/details/pricing/availability automatically, so the same generated OpenAPI flow works even before the website has a real API.

import {
  createMailflixActions,
  installRestaurantCatalog,
} from "@mailflix/actions";

export const mf = createMailflixActions({
  title: "Bistro Actions",
  secret: process.env.MAILFLIX_ACTIONS_SECRET,
});

installRestaurantCatalog(mf, {
  menuItems: [
    {
      id: "spicy-rigatoni",
      name: "Spicy Rigatoni",
      description: "Vodka sauce, basil, pecorino, Calabrian chili.",
      price: 24,
      currency: "$",
      category: "Pasta",
      allergens: ["dairy", "gluten"],
      tags: ["vegetarian"],
      popular: true,
    },
  ],
  reservationSlots: [
    { id: "fri-1830", date: "2026-05-08", time: "18:30", partySizeMax: 4 },
  ],
});
import { createMailflixActions, installRentalCatalog } from "@mailflix/actions";

export const mf = createMailflixActions({
  title: "Loft Rentals Actions",
  secret: process.env.MAILFLIX_ACTIONS_SECRET,
});

installRentalCatalog(mf, {
  items: [
    {
      id: "soho-loft",
      name: "SoHo daylight loft",
      price: 1250,
      currency: "$",
      period: "day",
      location: "SoHo",
      capacity: 40,
      tags: ["events", "photo shoots"],
    },
  ],
  availabilitySlots: [
    { id: "viewing-1", rentalId: "soho-loft", date: "2026-05-08", time: "10:30" },
  ],
});

Publishing

This package publishes compiled ESM and declarations from dist/.

pnpm --filter @mailflix/actions typecheck
pnpm --filter @mailflix/actions build
pnpm --filter @mailflix/actions publish --access public

Before publishing, confirm the npm account belongs to the @mailflix scope:

npm whoami