robfig/cron
a cron library for go
Healthy across all four use cases
Permissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓28+ active contributors
- ✓Distributed ownership (top contributor 30% of recent commits)
- ✓MIT licensed
Show 3 more →Show less
- ✓CI configured
- ✓Tests present
- ⚠Stale — last commit 2y ago
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/robfig/cron)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/robfig/cron on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: robfig/cron
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/robfig/cron shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across all four use cases
- 28+ active contributors
- Distributed ownership (top contributor 30% of recent commits)
- MIT licensed
- CI configured
- Tests present
- ⚠ Stale — last commit 2y ago
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live robfig/cron
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/robfig/cron.
What it runs against: a local clone of robfig/cron — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in robfig/cron | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | Last commit ≤ 700 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of robfig/cron. If you don't
# have one yet, run these first:
#
# git clone https://github.com/robfig/cron.git
# cd cron
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of robfig/cron and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "robfig/cron(\\.git)?\\b" \\
&& ok "origin remote is robfig/cron" \\
|| miss "origin remote is not robfig/cron (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 700 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~670d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/robfig/cron"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
robfig/cron is a Go library that executes scheduled jobs using standard cron syntax (minute, hour, day, month, day-of-week, and optional seconds). V3, released June 2019, introduced Go Modules support, extensible job chains/wrappers for cross-cutting concerns (panic recovery, job deduplication, logging), and conformance to standard cron spec by default instead of the non-standard seconds-first format. Single-package design: core scheduling logic in cron.go backed by parser.go for spec parsing (spec.go), option.go for configuration via WithSeconds/WithParser/WithLocation patterns, chain.go for job middleware/wrappers, constantdelay.go for scheduling strategies, and logger.go for pluggable logging. Tests are co-located (cron_test.go, parser_test.go, etc). No subpackages or monorepo structure.
👥Who it's for
Go backend engineers building services that need reliable, self-contained job scheduling without external dependencies like cron daemons or Redis. Common use cases: cleanup tasks, periodic data syncs, notification delivery, cache refreshes, and any time-triggered operations within a single Go application.
🌱Maturity & risk
Production-ready and actively maintained. The library has settled into v3 with a clear breaking-change migration path documented in the README. CI/CD (Travis CI) is configured, comprehensive test coverage exists (chain_test.go, cron_test.go, parser_test.go, spec_test.go), and the codebase is stable—v3 has been released since June 2019 and addresses years of accumulated bug fixes and feature requests from v1/v2.
Very low risk. Single-author (Rob Figueiredo) maintained library with no external dependencies (see go.mod minimal content), but this is actually a strength—fewer moving parts to break. The v2→v3 migration introduced breaking changes around cron spec parsing defaults (seconds field now optional, not first), so older code importing as 'gopkg.in' will break; however, the migration path is explicit and documented. No visible open issue backlog or PRs in the file list.
Active areas of work
The repository appears to be in maintenance mode post-v3 release. The README documents completed features (panic recovery chains, timezone support via WithLocation, seconds-field toggle via WithSeconds, breaking changes from v1/v2). No active PR/issue info visible in file list, but the library's scope is narrow and well-defined, suggesting active work happens via issues rather than visible branch activity.
🚀Get running
git clone https://github.com/robfig/cron.git
cd cron
go mod download
go test ./...
Daily commands:
This is a library, not an application. To test locally: go test ./.... To use in a project, import github.com/robfig/cron/v3 and instantiate with cron.New(), then call .AddFunc(schedule, job) and .Start().
🗺️Map of the codebase
- cron.go: Core Cron struct, Start/Stop/AddFunc/RemoveEntry methods, and the entry scheduling loop that drives all job execution
- parser.go: Cron spec parser that converts strings like '0 9 * * *' into schedule field specifications; defines Field type and parsing rules
- spec.go: Schedule interface implementation that calculates Next() execution time; core to determining when jobs run
- chain.go: Job wrapper/middleware pattern enabling panic recovery, deduplication, and logging; key extensibility mechanism in v3
- option.go: Functional options pattern implementation (WithSeconds, WithParser, WithLocation) for configurable Cron instantiation
- logger.go: Logger interface enabling pluggable structured logging; allows users to integrate their own logging infrastructure
- cron_test.go: Comprehensive integration tests covering job scheduling, removal, timing accuracy, and panic handling
🛠️How to make changes
Start in cron.go (main Cron struct and entry management). To add parser features, edit parser.go and add test cases to parser_test.go. To add job middleware, extend chain.go (study existing implementations like RecoverPanic). To adjust scheduling behavior, modify cron.go's runWithRecovery or entry.Next calculation. All changes need corresponding tests in *_test.go files.
🪤Traps & gotchas
- Cron spec field count matters: The default parser expects 5 fields (minute hour day month dow), NOT 6 with seconds. Must use cron.WithSeconds() or cron.WithParser(cron.NewParser(cron.SecondOptional | ...)) to parse specs with seconds—legacy code importing as 'gopkg.in/robfig/cron.v2' will have different field-order semantics. 2. Job panics crash the entry loop: Jobs that panic will stop that entry from scheduling future runs unless you wrap with chain.Recover(). 3. Location affects schedule calculation: Cron.New() uses time.Local by default; timezone-sensitive schedules need cron.WithLocation(loc) at construction time, not per-job. 4. No persistence: Cron state lives in memory; restarting the process loses all scheduled jobs and execution history.
💡Concepts to learn
- Cron Expression / Crontab Spec — The entire library is built around parsing and executing standard 5-field (or optional 6-field with seconds) cron expressions; understanding the spec format (minute hour day month day-of-week) is prerequisite to using this library
- Functional Options Pattern — robfig/cron uses this pattern (cron.New(cron.WithSeconds(), cron.WithLocation(loc))) for flexible, extensible configuration without constructor overloading; key pattern in modern Go API design
- Job Middleware / Interceptor Chains — The chain.go design allows wrapping job execution with cross-cutting concerns (panic recovery, deduplication, logging); understanding Chain and JobWrapper types is essential for production usage
- Next Occurrence Calculation — The spec.Next(time.Time) method determines when a job runs by calculating the next valid time matching the cron fields; core scheduling algorithm in spec.go
- Go Modules and Semantic Versioning — This library requires Go 1.11+ and uses semantic versioning with major version in import path (github.com/robfig/cron/v3); v3's breaking changes show how Go handles major version migrations
- Interface-Based Logging (go-logr compliance) — logger.go defines a Logger interface compatible with go-logr/logr, enabling pluggable logging without tight coupling to a specific logging library; exemplifies Go's composition-over-inheritance approach
🔗Related repos
go-co-op/gocron— Alternative Go job scheduling library with similar API but more ergonomic syntax (e.g., gocron.Every(1).Hour().Do(job)); used when simpler DSL is preferred over raw cron specsrk-project/rk-common— Scheduling utilities for Go microservices; complements cron for service-level job orchestration patternsgo-logr/logr— The structured logging interface standard that robfig/cron's logger.go implements, enabling users to plug in Zap, Slog, or other compatible loggersgolang/time— Go standard library (time package); robfig/cron builds atop time.Time, time.Location, and time.Ticker for all scheduling primitives
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add GitHub Actions workflow to replace Travis CI
.travis.yml exists but the repo should modernize to GitHub Actions for faster, more integrated CI/CD. This is valuable because Travis CI has shifted its pricing model and GitHub Actions is now the standard for GitHub-hosted projects. The README still references Travis CI badges, which should be updated.
- [ ] Create .github/workflows/test.yml with Go 1.12+ matrix testing
- [ ] Add workflow steps to run 'go test ./...' and 'go vet ./...'
- [ ] Update README.md badges from Travis CI to GitHub Actions status badge
- [ ] Verify all existing test files (cron_test.go, parser_test.go, chain_test.go, etc.) pass in CI
- [ ] Remove or deprecate .travis.yml
Add integration tests for real cron scheduling scenarios in cron_test.go
The repo has unit tests but lacks comprehensive integration tests covering realistic scheduling patterns. Current tests likely focus on parsing and basic functionality, but real-world scenarios like concurrent job execution, job overlap handling, and lifecycle edge cases need coverage to prevent regressions.
- [ ] Review existing cron_test.go to identify gaps in job execution scenarios
- [ ] Add integration tests for concurrent job execution with timing verification
- [ ] Add tests for job panic recovery (if chain.go provides recovery middleware)
- [ ] Add tests for Start/Stop/Restart lifecycle with pending jobs
- [ ] Add tests for multiple jobs with overlapping schedules to verify no race conditions exist
Add missing test coverage for logger.go and option.go interfaces
logger.go and option.go are listed in the file structure but there's no corresponding option_test.go shown explicitly for comprehensive coverage. These files define critical configuration interfaces that need tests to ensure custom loggers and options work correctly with the cron scheduler.
- [ ] Expand option_test.go to cover all option builder functions and their interactions
- [ ] Create logger_test.go to test custom logger implementations with different verbosity levels
- [ ] Add tests verifying logger is called at appropriate lifecycle events (start, stop, error)
- [ ] Add tests for option chaining and override scenarios
- [ ] Verify integration between options and the main cron.go initialization in cron_test.go
🌿Good first issues
- Add examples/ directory with runnable sample programs (e.g., examples/basic.go showing cron.New(), AddFunc, Start, with a wait loop; examples/logging.go showing custom logger implementation; examples/chains.go showing panic recovery and deduplication). Currently README has code snippets but no executable examples directory.
- Extend parser_test.go to cover edge cases around field validation: add test cases for invalid day-of-month (e.g., Feb 30), confirm 0-based vs 1-based indexing for each field, test boundary conditions like minute=59/60. The parser has good coverage but edge cases around validation rules could be more explicit.
- Add integration test in cron_test.go for timezone-aware scheduling: verify that a job scheduled in one timezone actually runs at the correct local time when the system timezone changes, or when explicitly set via WithLocation. Current tests may not cover daylight-saving-time transitions or location switching.
⭐Top contributors
Click to expand
Top contributors
- [@Rob Figueiredo](https://github.com/Rob Figueiredo) — 30 commits
- @robfig — 26 commits
- @daft-panda — 7 commits
- @lukescott — 4 commits
- [@Bulat Gaifullin](https://github.com/Bulat Gaifullin) — 3 commits
📝Recent commits
Click to expand
Recent commits
bc59245— fix: gracefully quit jobWrapper SkipIfStillRunning (XiaoXiaoSN)6a8421b— fix readme custom parser example (vankofalcon)208b4f7— updated comments on parser example (haseth)e7da914— Fix syntax highlighting (#264) (DannyFeliz)ccba498— chain/SkipIfStillRunning: fix bug handling different jobs (Rob Figueiredo)3d516cc— Merge pull request #268 from nnao45/fix/readme-link (robfig)64a083c— Fix changing quartz scheduler site link for README (nnao45)b7cc47d— Merge pull request #243 from yvanoers/master (robfig)3a6eb7f— Merge pull request #253 from cettoana/patch-1 (robfig)7d0ec89— docs: remove redundant asterisk in example (cettoana)
🔒Security observations
The cron library codebase shows good security practices overall. No hardcoded credentials, injection vulnerabilities, or Docker/infrastructure issues were detected. The main concerns are minor: outdated Go version specification in go.mod and incomplete documentation. The library appears to be a pure Go utility library without external dependencies, reducing supply chain risk. Recommendations focus on modernizing the Go version requirement and completing documentation for better maintainability.
- Low · Outdated Go Version Requirement —
go.mod. The go.mod file specifies 'go 1.12' which is outdated and no longer receives security updates. Go 1.12 reached end-of-life in October 2020. While the README mentions Go 1.11 requirement, the actual module specification should target a more recent, actively maintained version. Fix: Update the Go version requirement to at least 1.20 or the latest stable release (1.21+) to receive security patches and bug fixes. Update go.mod with 'go 1.21' or later. - Low · Incomplete README Documentation —
README.md. The README.md file appears truncated (ends mid-sentence: 'some backwards-incompatible f'). This incomplete documentation may cause confusion and potentially obscure important security-related information about breaking changes or security considerations. Fix: Complete the README documentation to ensure all users have clear, comprehensive guidance on security considerations, breaking changes, and proper usage patterns.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.