webdevpuneet.com

Cron Expression Builder — Free HTML CSS JS Snippet

Cron Expression Builder · Tools · Plain HTML, CSS & JS · Live preview

Copy & paste

Source Code

<div class="cx-wrap">
  <div class="cx-head">
    <h3>Schedule</h3>
    <p class="cx-sub">Build a cron expression, or type one and see it explained.</p>
  </div>

  <div class="cx-presets" id="cxPresets">
    <button class="cx-preset" data-cron="*/5 * * * *">Every 5 min</button>
    <button class="cx-preset" data-cron="0 * * * *">Hourly</button>
    <button class="cx-preset" data-cron="30 2 * * *">Nightly 02:30</button>
    <button class="cx-preset" data-cron="0 9 * * 1-5">Weekdays 09:00</button>
    <button class="cx-preset" data-cron="0 0 1 * *">Monthly</button>
  </div>

  <div class="cx-fields">
    <label class="cx-f">
      <span>Minute</span>
      <input id="cxMin" type="text" spellcheck="false" autocomplete="off" value="30">
    </label>
    <label class="cx-f">
      <span>Hour</span>
      <input id="cxHour" type="text" spellcheck="false" autocomplete="off" value="2">
    </label>
    <label class="cx-f">
      <span>Day of month</span>
      <input id="cxDom" type="text" spellcheck="false" autocomplete="off" value="*">
    </label>
    <label class="cx-f">
      <span>Month</span>
      <input id="cxMon" type="text" spellcheck="false" autocomplete="off" value="*">
    </label>
    <label class="cx-f">
      <span>Day of week</span>
      <input id="cxDow" type="text" spellcheck="false" autocomplete="off" value="*">
    </label>
  </div>

  <div class="cx-out">
    <div class="cx-exp">
      <code id="cxExp">30 2 * * *</code>
      <button class="cx-copy" id="cxCopy">Copy</button>
    </div>
    <p class="cx-human" id="cxHuman">At 02:30, every day.</p>
  </div>

  <div class="cx-next">
    <span class="cx-next-label">Next 5 runs</span>
    <ul id="cxRuns"></ul>
  </div>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month, 7 days free), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Real cron parsing: *, numbers, a-b ranges, */n and a-b/n steps, and comma-separated lists
Per-field validation against legal ranges, marking the offending input and naming the field
Plain-English description generated from the parsed value sets, not matched against canned templates
Correct day-of-month / day-of-week OR semantics, the rule most cron helpers implement wrongly
Next five run times computed by minute-stepping and testing, not estimated
Iteration cap so an impossible expression reports "never runs" instead of freezing the tab
Duplicate value de-duplication so overlapping lists like 1-5,3 behave correctly
Preset chips that write all five fields and re-highlight by comparing the generated expression
Clipboard API copy with a confirmation state, and no dependencies anywhere

About this UI Snippet

Cron Expression Builder — Field Expansion, Plain-English Descriptions & Real Next-Run Calculation

Screenshot of the Cron Expression Builder snippet rendered live

Cron syntax is five fields of terse punctuation that almost nobody reads confidently, and the cost of misreading one is a job that runs a thousand times more often than intended — or never. This snippet is a builder and an explainer in one: edit any field and the expression, a plain-English description, and the next five actual run times all update together, so the schedule is verified before it ships rather than after the pager goes off.

Expanding fields rather than pattern-matching them

Most cron helpers work by matching the expression against a table of known shapes and printing a canned sentence, which means anything slightly unusual falls through to "custom schedule". This one parses properly. expand() turns any field into the explicit list of values it matches, handling *, single numbers, a-b ranges, */n and a-b/n steps, and comma-separated combinations of all of those. Because everything downstream works from those value sets rather than from the original string, the description and the run-time preview handle expressions the author never anticipated.

Validation that names the field

expand() returns null for anything outside its field's legal range — minute 61, month 0, a reversed range, a zero step — and the caller marks that specific input red and reports which field is wrong by name. Cron's failure mode is normally silent acceptance followed by wrong behaviour, so catching 0-70 in the minute field at the moment of typing is most of this component's value.

The day-of-month / day-of-week OR rule

This is the part real implementations get wrong. When both the day-of-month and day-of-week fields are restricted, standard cron treats them as an OR, not an AND: 0 0 1 * 1 fires on the 1st of the month *and* on every Monday, not only on Mondays that fall on the 1st. The matcher checks whether each field is restricted and switches between OR and AND accordingly, and the description says "on day 1 or Monday" so the behaviour is visible rather than surprising.

Next runs computed, not guessed

The preview walks forward minute by minute from now, testing each candidate against the parsed sets, and collects the first five matches. That is a brute-force search rather than a clever date calculation, and at one iteration per minute it finds a daily schedule in well under a second. The loop is capped at roughly four years so an expression that can never fire — 30 February, say — terminates and reports "This expression never runs" instead of hanging the tab, which is the failure mode any minute-stepping scheduler needs to guard against.

Presets that stay in sync

The preset chips write all five fields at once, and after every edit the current expression is compared back against the preset list so the matching chip highlights itself. Typing the equivalent expression by hand lights the same chip, because the sync compares the generated string rather than tracking which button was last clicked.

Step by step

How to Use

  1. 1
    Start from a preset or from scratchThe chips across the top write all five fields at once. The matching chip highlights whenever the current expression equals it, including when you type that expression by hand.
  2. 2
    Edit any of the five fieldsEach field accepts full cron syntax: * for every value, a single number, a-b ranges, */n steps, a-b/n stepped ranges, and comma-separated lists combining any of those.
  3. 3
    Read the plain-English descriptionThe sentence under the expression describes what the schedule actually does, staying quiet about fields set to the whole range so it reads naturally rather than restating every field.
  4. 4
    Check the next five run timesReal dates and times computed by walking forward from now and testing each minute, so you can confirm the schedule fires when you expect before deploying it.
  5. 5
    Watch for validation errorsAn out-of-range or malformed field turns red immediately and the description names which field is wrong — minute 61 or a reversed range is caught as you type rather than by your scheduler at 3am.
  6. 6
    Copy the finished expressionThe Copy button writes the assembled five-field string to the clipboard via the Clipboard API and confirms with a short success state.

Real-world uses

Common Use Cases

Scheduling UI in an admin or automation product
Any product exposing cron to users needs this pairing of builder and explainer. Combine it with a timezone converter so the schedule and the timezone it runs in are decided in the same place.
CI/CD and job runner configuration screens
Pipeline schedules, backup windows and report generation are all cron under the hood. Showing the next five runs turns "is this right?" from a question answered by waiting a day into one answered immediately.
Teaching cron syntax
Because the description regenerates on every keystroke, editing a field and watching the sentence and the run times change is a far faster way to learn the syntax than reading the crontab manual page.
Reference for parsing a small domain grammar
The expand-then-derive structure here — parse into explicit sets first, then generate description, validation and matching from those sets — is the right shape for any small expression language, and much more robust than string pattern matching.
Reminder and notification scheduling for end users
Hide the raw fields behind the presets and keep the description and next-run list, and this becomes a friendly recurring-reminder picker that still produces a standard cron string for your backend.
Internal tools where the schedule is the risk
Data pipelines and billing jobs are where a misread cron field becomes expensive. A visible next-run list in the form is a cheap, permanent guard against the whole class of mistake.
Related: Debounce vs Throttle Visualizer
See the Debounce vs Throttle Visualizer for a related forms pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

That is standard cron behaviour, and it surprises almost everyone. When both fields are restricted, a job fires if EITHER matches — so 0 0 1 * 1 runs on the 1st of every month and on every Monday. The matcher checks whether each field is restricted and switches between OR and AND to match real cron, and the description says "or" so the behaviour is visible in the UI.

By walking forward from the current minute and testing each candidate minute against the parsed value sets, collecting the first five matches. It is brute force rather than a closed-form date calculation, which keeps the logic short and correct; a daily schedule resolves in a few hundred thousand cheap iterations, well under a second.

The search loop is capped at roughly four years of minutes. An expression that can never fire — 30 February, or 31 in a month field set to February — exhausts the cap and the UI reports "This expression never runs" rather than looping forever. Any minute-stepping scheduler needs this guard.

The standard five-field format with *, single values, a-b ranges, */n and a-b/n steps, and comma-separated lists of any combination. Non-standard extensions — @reboot, @daily, L for last day, W for weekday, # for nth weekday, and named months or days like JAN and MON — are not parsed; expand() would return null and flag the field.

Yes. The preview is built with the browser's Date object, so it reflects the local timezone of whoever is looking. Since servers usually run cron in UTC, a production version should let the user pick the target timezone and compute against that — otherwise a schedule that looks correct locally fires at a different hour in production.

Yes, and it fits component state well. Hold the five field strings in state, and derive the expression, validation, description and run list with a memoised function of those five values — they are all pure functions of the input, so useMemo in React or a computed property in Vue removes any need for manual update() calls.