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

@vite-hub/schedule

v0.0.3

Published

Schedule primitives and definition discovery for ViteHub.

Downloads

3,136

Readme

@vite-hub/schedule

@vite-hub/schedule keeps cron definitions and runtime schedules behind one schedule registry.

Install

pnpm add @vite-hub/schedule

Add @vite-hub/kv when using the default KV-backed stores or the generated Process Runtime. Static Schedules, memory stores, and custom ScheduleKVStorage implementations do not require it.

Minimal API

// server/schedules/daily-report.ts
import { defineSchedule } from "@vite-hub/schedule"

export default defineSchedule({
  cron: "0 8 * * *",
  allowRuntimeSchedules: true,
  handler: async ({ scheduledAt }) => {
    console.log(`Generating daily report for ${scheduledAt.toISOString()}`)
  },
})
// server/schedules/report.ts
import { defineScheduleTarget } from "@vite-hub/schedule"

export default defineScheduleTarget<{ prompt: string }>({
  handler: async ({ input }) => {
    if (input) await generateReport(input.prompt)
  },
})
// server/api/schedules.post.ts
import { schedules } from "@vite-hub/schedule/runtime"
import { defineEventHandler } from "h3"

export default defineEventHandler(() => {
  return schedules.create({
    cron: "30 3 * * 1",
    input: { prompt: "Summarize yesterday" },
    target: "report",
    timeZone: "Europe/Copenhagen",
  })
})

Runtime Schedule updates preserve timeZone when it is omitted; set it to UTC to reset UTC evaluation. DST gaps skip missing local occurrences, and DST overlaps run both repeated instants.

// vite.config.ts
import { hubSchedule } from "@vite-hub/schedule/vite"
import { defineConfig } from "vite"

export default defineConfig({
  plugins: [
    hubSchedule({
      runtime: {
        driver: "process",
        prefix: "my-app:schedule",
      },
    }),
  ],
})

The explicit process runtime generates Nitro wiring for a long-running process. It runs discovered Static Schedule Definitions and persisted Runtime Schedules through one driver queue, creates both stores through the default KV store configured by hubKv(), applies the Schedule prefix, and closes the driver with Nitro. The defaults are prefix vitehub:schedule, intervalMs: 60_000, and concurrency: 1; the interval cannot exceed the one-minute cron resolution. providerOutput remains independent, so static provider wake output can be enabled or disabled separately.

Run exactly one long-lived process or replica with this driver. The KV run store records occurrences but does not provide distributed leader election or locking. Do not select the process driver for request-scoped or serverless hosts that may stop between requests. Those hosts need a provider or host wake integration through @vite-hub/schedule/runtime/driver.

Vite Integration

Use hubSchedule() in Vite to discover server/schedules/<name>.ts and src/<name>.schedule.ts. defineSchedule() declarations can produce provider cron output, including Vercel Cron Jobs. Cronless defineScheduleTarget() declarations are available only to Runtime Schedules and never emit static provider output. For Nitro apps on Cloudflare, Schedule Provider Wake writes generated .vitehub/nitro/schedule/* files so Nitro can register the cloudflare:scheduled runtime hook and emit cloudflare.wrangler.triggers.crons during standalone nitro build. In Nuxt apps, install @vite-hub/schedule/nuxt so the same Provider Wake output is merged into Nuxt's top-level Nitro config. In automatic mode, server/schedules/* routes through Nitro Provider Wake while suffix schedules keep standalone provider output.

Runtime Schedule input is opaque to Schedule. Create stores a snapshot; update replaces the complete snapshot when input is provided and preserves it when omitted. The configured store must support the value's serialization requirements.

When a host owns its own Cloudflare scheduled-event bridge, use the runtime helper instead of reimplementing registry matching:

import scheduleRegistry from "#vitehub/schedule/registry"
import { executeCloudflareStaticSchedules } from "@vite-hub/schedule/runtime/static"

export default {
  async scheduled(event) {
    await executeCloudflareStaticSchedules(event, { registry: scheduleRegistry })
  },
}

Cron parsing uses cron-schedule.

Runtime Wake Drivers

Host integrations can connect dynamic Runtime Schedules to a native scheduler through @vite-hub/schedule/runtime/driver:

import { installScheduleRuntime } from "@vite-hub/schedule/runtime/driver"

const controller = await installScheduleRuntime({
  createDriver: context => hostScheduler.driver(context),
  registry: scheduleRegistry,
  runtimeScheduleStore,
  scheduleRunStore,
})

The driver receives the complete stored Runtime Schedule snapshot, including disabled records. Installation finishes only after the initial snapshot is reconciled. Later creates, updates, and deletes persist first, reconcile serially, and roll back the stored record if host reconciliation fails. A native wake calls context.wake({ scheduleId, scheduledAt }); controller.close() releases driver resources without deleting schedule state.

Long-running hosts can use createProcessScheduleWakeDriver() from @vite-hub/schedule/runtime/process when they install the runtime directly. It keeps wake registration inside the current process; it does not install cron, systemd, or another operating-system scheduler.

startScheduleRunner() has been removed. Existing self-hosted processes should install createProcessScheduleWakeDriver() through installScheduleRuntime() as shown above, then await controller.close() during host shutdown.

Learn more at vitehub.dev.