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

shipany-ai-generator

v0.1.29

Published

Shared AI image/video generator configuration and runtime core.

Readme

shipany-ai-generator

Shared AI image/video generator runtime and ShipAny-style React UI.

This package is designed for ShipAny/Next/Tailwind template variants. Keep the component code in one package, and let each project provide its own model configuration, API adapter, login, credits, paywall, and copy.

Recommended Workflow

Use one project as the baseline dogfood project.

  1. Develop and test the generator in the baseline project with real auth, credits, uploads, paywall, Tailwind theme, and API routes.
  2. Build and publish a new package version.
  3. Upgrade other template projects to the new npm package version.

Do not copy generator source files between projects once the package is in use. Other projects should keep only their own config and adapter wiring.

Install

pnpm add shipany-ai-generator

Required peer dependencies are expected to already exist in ShipAny template projects:

pnpm add react framer-motion lucide-react

If the consuming project uses Tailwind CSS v4, scan the package output so the ShipAny skin classes are generated:

@import 'tailwindcss';
@source '../../node_modules/shipany-ai-generator/dist';

Adjust the relative path to match the app's CSS file location.

ShipAny UI Usage

'use client';

import { createFetchGeneratorAdapter } from 'shipany-ai-generator/adapters';
import { ShipAnyGenerator } from 'shipany-ai-generator/shipany';

const adapter = createFetchGeneratorAdapter({
  generateUrl: '/api/ai/generate',
  queryUrl: '/api/ai/query',
  cancelUrl: '/api/ai/cancel',
  uploadUrl: '/api/storage/upload-image',
  downloadUrl: '/api/proxy/file',
  transformRequest(request) {
    const options = { ...request.options };

    if (request.inputImages.length > 0) {
      options.image_input = request.inputImages;
    }

    return {
      mediaType: request.outputType,
      scene: request.scene,
      provider: request.provider,
      model: request.model,
      prompt: request.prompt,
      options,
    };
  },
});

export function Generator({ user, isPaid, credits }) {
  return (
    <ShipAnyGenerator
      config={videoConfig}
      adapter={adapter}
      app={{
        user,
        isPaid,
        isPaidReady: true,
        credits: {
          remaining: credits?.remainingCredits ?? 0,
          unlimited: credits?.isUnlimited,
        },
        requestSignIn: () => openSignInDialog(),
        openPaywall: () => openPaymentDialog(),
        notify: {
          success: (message) => toast.success(message),
          error: (message) => toast.error(message),
          info: (message) => toast.message(message),
        },
        track: (event, payload) => track(event, payload),
      }}
      estimateCredits={(request) => estimateProjectCredits(request)}
      onResult={() => refreshCredits()}
    />
  );
}

estimateCredits is optional. If omitted, the package uses its legacy generic estimate. Projects that configure their own models or credit rules should pass their own estimator and use the same function on the server when charging credits.

Config Examples

Video Generator

import { createKieVideoGeneratorConfig } from 'shipany-ai-generator';

export const videoConfig = createKieVideoGeneratorConfig({
  demoVideos: ['/videos/demo-1.mp4', '/videos/demo-2.mp4'],
});

createKieVideoGeneratorConfig() includes the default Kie video model presets:

  • Kling 3.0 (kling-3.0) maps requests to kling-3.0/video, supports std / pro / 4K, 16:9 / 9:16 / 1:1, durations from 3 to 15 seconds, one start-frame image, or two first/last-frame images.
  • Veo 3.1 (veo3) maps modes to veo3_lite, veo3_fast, and veo3, supports 16:9 / 9:16 / auto, text, first/last-frame, and reference generation types. Reference mode is normalized to fast and allows up to 3 input images. 1080p and 4k are marked as paid options by default.
  • Seedance 2.0 (seedance-2) maps requests to bytedance/seedance-2, supports 480p / 720p / 1080p, 16:9 / 4:3 / 1:1 / 3:4 / 9:16 / 21:9, up to 9 reference images, and two first/last-frame images. generate_audio defaults to false.

The default list intentionally does not include Seedance 2.0 Fast unless a project wires that provider path itself.

Projects can crop or lock video options the same way as image options:

import {
  createKieVideoGeneratorConfig,
  KIE_VIDEO_MODEL_PRESETS,
} from 'shipany-ai-generator';

const kling = KIE_VIDEO_MODEL_PRESETS.find(
  (model) => model.id === 'kling-3.0'
)!;

export const videoConfig = createKieVideoGeneratorConfig({
  models: [
    {
      ...kling,
      modeOptions: [
        { value: 'std', label: 'Standard' },
        {
          value: '4K',
          label: '4K',
          requiresPaid: true,
          paywallFeature: 'video_4k',
        },
      ],
    },
  ],
});

Image Generator

import { createKieImageGeneratorConfig } from 'shipany-ai-generator';

export const imageConfig = createKieImageGeneratorConfig({
  defaultPrompt: 'Draw this in rough MS Paint style.',
  defaultModel: 'gpt-image-2',
  promptPlaceholder: 'Upload an image, then describe the redraw.',
  defaultOutputCount: 1,
  outputCountOptions: [
    { value: 1, label: '1 image' },
    { value: 2, label: '2 images' },
    { value: 4, label: '4 images' },
  ],
  demoImages: ['/imgs/demo.webp'],
});

createKieImageGeneratorConfig() includes the default Kie image model presets:

  • GPT Image 2 (gpt-image-2) maps requests to gpt-image-2-text-to-image or gpt-image-2-image-to-image, defaults to 1K + auto, supports 16 input images, and changes aspect ratio options by resolution.
  • Nano Banana 2 (nano-banana-2) defaults to 2K + auto + jpg, supports 14 input images, 1K / 2K / 4K, jpg / png, and the full Kie aspect ratio set.

GPT Image 2 aspect ratio options depend on resolution:

| Resolution | Aspect ratios | | ---------- | ------------------------------------------- | | 1K | auto, 1:1, 9:16, 16:9, 4:3, 3:4 | | 2K | 1:1, 9:16, 16:9, 4:3, 3:4 | | 4K | 9:16, 16:9, 4:3, 3:4 |

The UI hides invalid combinations, and buildGeneratorRequest() normalizes stale local-storage or URL state before sending a request. For example, gpt-image-2 + 4K + 1:1 is converted to a valid preset default instead of being submitted to Kie.

Projects can crop or lock preset options by passing their own models array or option objects. Use requiresPaid and paywallFeature on any option that should open the paywall:

import {
  createKieImageGeneratorConfig,
  KIE_IMAGE_MODEL_PRESETS,
} from 'shipany-ai-generator';

const gptImage2 = KIE_IMAGE_MODEL_PRESETS.find(
  (model) => model.id === 'gpt-image-2'
)!;

export const imageConfig = createKieImageGeneratorConfig({
  models: [
    {
      ...gptImage2,
      defaultResolution: '2K',
      resolutionOptions: [
        { value: '2K', label: '2K' },
        {
          value: '4K',
          label: '4K',
          requiresPaid: true,
          paywallFeature: 'image_4k',
        },
      ],
    },
  ],
});

Output Count

The package supports configurable image output count. This is different from maxImages:

  • maxImages controls how many input/reference images the user may upload.
  • defaultOutputCount controls how many generated images are requested by default.
  • outputCountOptions controls which output counts appear in Settings.

Example:

{
  "outputType": "image",
  "defaultOutputCount": 1,
  "outputCountOptions": [
    { "value": 1, "label": "1 image" },
    { "value": 2, "label": "2 images" },
    { "value": 4, "label": "4 images" }
  ]
}

The selected value is saved in local storage with the rest of the generator settings. When the user submits, the package sends both:

request.options.output_count; // generic package field
request.options.image_count; // image-specific backend field

Current backend support:

  • Go Worker Kie image generation supports image_count from 1 to 4.
  • Go Worker clamps invalid values to the 1-4 range.
  • Go Worker generates each image as a separate Kie task and returns all image URLs together.
  • Video generation currently remains single-output by default. Do not expose outputCountOptions for video models unless the backend/provider explicitly supports multi-video generation and the billing model is updated.

Billing must multiply image cost by the selected output count. In this template, /api/ai/generate reads options.image_count or options.output_count and multiplies image credits by that value.

For project wrappers, only expose output count when the configured provider supports it. In the current ShipAny wrapper, output count is shown for the go-worker provider and hidden for direct kie provider to avoid displaying a control that the provider path does not honor.

URL Contract

The package reads these query params automatically:

  • Prompt: prompt, prompts; multiple values or comma-separated values use the last one.
  • Preview images: previewImage, previewImages, previewImg, previewImgs.
  • Preview videos: previewVideo, previewVideos.
  • Input images: inputImage, inputImages, referenceImage, referenceImages.
  • Bare media keys are preview-only: image, img, images, video, videos.

Input images affect scene inference. Bare media keys do not.

Runtime Behavior

  • Scene is inferred from outputType and uploaded/input images.
  • text-to-video / image-to-video and text-to-image / image-to-image are handled by one input box.
  • If the user clicks generate while signed out, requestSignIn is called and generation resumes after login if the prompt is unchanged.
  • Uploaded images are limited by model-level maxImages first, then config-level maxImages, plus maxSizeMB.
  • Multiple demo media and multiple result URLs are shown with thumbnail switching.
  • Download uses adapter.download when provided; createFetchGeneratorAdapter({ downloadUrl }) downloads through a proxy endpoint.

Adapter Contract

type GeneratorAdapter = {
  generate(request: GeneratorRequest): Promise<unknown>;
  query?(taskId: string): Promise<unknown>;
  cancel?(taskId: string): Promise<void>;
  download?(url: string): Promise<Blob>;
  uploadImages?(files: File[]): Promise<string[]>;
};

createFetchGeneratorAdapter expects JSON responses shaped either as raw data or { code, message, data }. Upload responses may return URL strings or objects with url, src, imageUrl, or uri.

Exports

import {
  buildGeneratorRequest,
  type GeneratorConfig,
} from 'shipany-ai-generator';
import { createFetchGeneratorAdapter } from 'shipany-ai-generator/adapters';
import { AiGenerator } from 'shipany-ai-generator/react';
import { ShipAnyGenerator } from 'shipany-ai-generator/shipany';

Publishing a New Version

From the baseline project:

pnpm --filter shipany-ai-generator build
pnpm -C packages/ai-generator pack --pack-destination /tmp

Then bump packages/ai-generator/package.json:

{
  "name": "shipany-ai-generator",
  "version": "0.1.x"
}

Publish:

pnpm -C packages/ai-generator publish --access public --registry=https://registry.npmjs.org/

After publishing, upgrade consumers:

pnpm add [email protected]