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

natty-sched

v1.3.3

Published

Natural language scheduler with autocomplete - Parse human-readable schedules to JSON, calculate next run times, and get smart suggestions. Supports 'every 3 days', 'weekdays at 9am', 'first Monday of month', with typo tolerance and 95+ templates.

Readme

Natural Scheduler

Natural-language schedule and datetime autocomplete for apps that need user-friendly time input.

natty-sched gives you three core workflows:

  • schedule autocomplete and resolution for recurring rules like every friday at 5pm
  • datetime autocomplete and resolution for one-time moments like tomorrow morning
  • a combined mode when the user might mean either

It is built for product input fields, not just raw parsing. The resolver functions use the same code path as autocomplete, so the value a user selects is the same value you get when resolving that exact string later.

Install

npm install natty-sched

Browser / unpkg

The package ships a UMD bundle for browser use:

<script src="https://unpkg.com/natty-sched/dist/natty-sched.umd.js"></script>
<script>
  const results = NattySched.autocompleteDatetime('today', new Date(), true, {
    limit: 5,
    includeValue: true
  });
  console.log(results);
</script>

Exported Functions

const {
  autocomplete,
  autocompleteSchedule,
  autocompleteDatetime,
  resolveString,
  resolveScheduleString,
  resolveDatetimeString,
  calcNextScheduledTime
} = require('natty-sched');

Quick Start

1. Recurring schedules

const { autocompleteSchedule, resolveScheduleString, calcNextScheduledTime } = require('natty-sched');

const suggestions = autocompleteSchedule('every fri', {
  limit: 5,
  includeValue: true
});

const schedule = resolveScheduleString('every friday at 5pm');
const nextRun = calcNextScheduledTime(schedule, {
  from: new Date('2026-03-15T12:00:00')
});

2. One-time datetimes

const { autocompleteDatetime, resolveDatetimeString } = require('natty-sched');

const referenceDate = new Date('2026-03-15T13:37:00');

const suggestions = autocompleteDatetime('today', referenceDate, true, {
  limit: 10,
  includeValue: true
});

const value = resolveDatetimeString('Now', referenceDate, true);
// => { datetime: '2026-03-15T13:37:00', timestamp: 1773596220000 }

3. Mixed input fields

const { autocomplete, resolveString } = require('natty-sched');

const results = autocomplete('friday', {
  limit: 10,
  includeValue: true
});

const value = resolveString('every friday at 5pm');

Returned Shapes

Schedule suggestion

{
  label: 'Every Friday at 5 PM',
  input: 'Every Friday at 5 PM',
  value: {
    start: '2026-03-15T17:00:00',
    repeat: {
      interval: { unit: 'week', count: 1 },
      on: { weekdays: ['fri'] },
      at: '17:00'
    }
  },
  score: 0.94,
  source: 'template',
  type: 'schedule'
}

Datetime suggestion

{
  label: 'Tomorrow morning',
  input: 'Tomorrow morning',
  value: {
    datetime: '2026-03-16T09:00:00',
    timestamp: 1773666000000
  },
  score: 0.91,
  source: 'datetime',
  type: 'datetime'
}

Core API

autocomplete(input, options?)

autocomplete(input, referenceDate, excludePast?, options?)

Combined autocomplete for schedule and datetime input.

Useful when the user may type either a recurring rule or a one-time date/time.

Options:

  • limit default 10
  • includeValue default true
  • minScore default 0.3
  • referenceDate for relative datetime resolution
  • excludePast to omit datetime results before referenceDate
  • allowRecurring default true
  • allowOneTime default true
  • category to filter schedule suggestions by category
  • defaultTime to control fallback time for datetime resolution
  • wheneverDays to control the random window used for whenever

Example:

const results = autocomplete('today', new Date('2026-03-15T13:37:00'), true, {
  limit: 10,
  includeValue: true
});

autocompleteSchedule(input, options?)

autocompleteSchedule(input, referenceDate, excludePast?, options?)

Schedule-only autocomplete.

This produces recurring schedule suggestions only.

Example:

autocompleteSchedule('every 2', { limit: 5, includeValue: true });
autocompleteSchedule('', { limit: 10, category: 'Monthly' });

autocompleteDatetime(input, options?)

autocompleteDatetime(input, referenceDate, excludePast?, options?)

Datetime-only autocomplete.

This produces one-time datetime suggestions only.

Datetime-specific options:

  • referenceDate
  • excludePast
  • defaultTime
  • wheneverDays
  • limit
  • includeValue
  • minScore

When excludePast is true, only datetimes at or after referenceDate are returned. Now is still allowed.

If input is '' or null, the default popular datetime suggestions are returned:

  • Now
  • In 1 hour
  • Tomorrow morning
  • Monday at 8 AM
  • In 1 week
  • 1 month from now
  • Next year
  • Tonight
  • Friday at 5 PM
  • Christmas

Example:

const defaults = autocompleteDatetime('', new Date('2026-03-15T13:37:00'), true, {
  limit: 10,
  includeValue: true
});

Resolver Functions

The resolver functions are designed so there is no drift between:

  • what autocomplete says a string means
  • what your app later resolves that same string to

That is the main contract of this library.

resolveScheduleString(input, options?)

resolveScheduleString(input, referenceDate, excludePast?, options?)

Returns the exact schedule JSON that the schedule autocomplete pipeline would attach to that input.

const schedule = resolveScheduleString('every day at 9am');

resolveDatetimeString(input, options?)

resolveDatetimeString(input, referenceDate, excludePast?, options?)

Returns the exact { datetime, timestamp } value that the datetime autocomplete pipeline would attach to that input.

const value = resolveDatetimeString('Now', new Date('2026-03-15T13:37:00'), true);

resolveString(input, options?)

resolveString(input, referenceDate, excludePast?, options?)

Returns the exact value from the combined autocomplete pipeline.

const value1 = resolveString('Now', new Date('2026-03-15T13:37:00'), true);
const value2 = resolveString('every friday at 5pm');

Notes:

  • blank input returns null for all resolver functions
  • if there is no exact normalized match, the resolver falls back to the top autocomplete result for that input

calcNextScheduledTime(schedule, options?)

Calculates the next run time for a resolved schedule.

Parameters:

  • schedule: schedule JSON from resolveScheduleString or schedule autocomplete
  • options.from: calculate from this date, default now
  • options.asTimestamp: when true, return unix milliseconds instead of Date

Example:

const schedule = resolveScheduleString('every friday at 5pm');

const nextDate = calcNextScheduledTime(schedule, {
  from: new Date('2026-03-15T12:00:00')
});

const nextTimestamp = calcNextScheduledTime(schedule, {
  from: new Date('2026-03-15T12:00:00'),
  asTimestamp: true
});

Supported Input Examples

Schedule examples

'every day at 9am'
'weekdays at 8:30am'
'mondays and fridays at 5pm'
'every 3 days at noon'
'first monday of the month at 9am'
'every year on december 31st at 11:59pm'

Datetime examples

'now'
'tomorrow morning'
'tonight'
'friday at 5pm'
'in 2 weeks'
'1 month from now'
'christmas evening'

Common Patterns

Build a mixed input field

function getSuggestions(text) {
  return autocomplete(text, new Date(), true, {
    limit: 8,
    includeValue: true
  });
}

Store exact values from selected text later

const selectedText = 'Tomorrow morning';
const value = resolveDatetimeString(selectedText, referenceDate, true);

Resolve recurring schedules and compute next run

const schedule = resolveScheduleString('every monday at 10am');
const nextRun = calcNextScheduledTime(schedule, { from: new Date() });

Notes

  • referenceDate can be a Date, ISO string, or unix milliseconds
  • excludePast only affects datetime behavior
  • if no time is specified for datetime resolution, the current time-of-day from referenceDate is used as the default
  • browser builds use the local timezone of the runtime environment

Verification

Current repo checks:

  • npm test
  • node test-datetime-autocomplete.js
  • npm run build:umd