Files
The content root is one flat folder of plain JavaScript, mirrored to your server as a whole. Every path in it falls into exactly one of three roles: an entry point (a job), a supporting file (imported, never run), or ignored (never synced). This page is the definitive map from path to role.
A content root
cron/ the content root ("contentRoot" in config.json)
digest.every.30m.cron.js entry point → every 30 minutes
backup.daily.0300.cron.js entry point → daily at 03:00 UTC
report.hourly.00.cron.js entry point → at :00 past the hour
report.hourly.30.cron.js entry point → at :30 (same base name)
lib/ supporting sub-folder
format.js supporting file (imported by jobs)
mailer.js supporting file
node_modules/ supporting — vendored deps, resolved normally
_draft.every.10s.cron.js ignored (leading _)
_env.json ignored secrets, read by the runner on the server
.gitignore ignored (dotfile)
Path patterns
| Path pattern | Role | Notes |
|---|---|---|
<name>.every.<N><unit>.cron.js (top level) | Entry point | Interval job. See Schedules. |
<name>.daily.<time>.cron.js (top level) | Entry point | Daily clock job. |
<name>.hourly.<time>.cron.js (top level) | Entry point | Hourly clock job. |
*.js (top level, no schedule keyword) | Supporting file | Imported by jobs; never invoked on its own. |
<subdir>/** (any nested path) | Supporting file | Never an entry point, even if the filename looks like a schedule — the entry-point test is top-level only. |
node_modules/** | Supporting file | Synced and resolved by require/import like any dependency. |
_* (any file or folder starting with _) | Ignored | Never synced, never run. Drafts and secrets. |
.* (dotfiles/dotfolders) | Ignored | Editor and VCS cruft stays local. |
_env.json | Ignored | Secrets file; a special case of the _ rule — see below. |
Naming rules
- An entry point must be a top-level file whose name ends
.cron.jsand contains a schedule keyword with a valid time token. Nested files are never entry points. - The base name — everything before the schedule keyword — is the job's identity and its mutex key. Keep it distinct unless you intend two files to share a schedule mutex (the duplicate idiom).
- Time tokens are zero-padded and range-checked (
HH00–23,MM/SS00–59); intervalNis any positive integer. An out-of-range or malformed token means the file is not recognised as an entry point — it falls through to being a supporting file, so a typo silently stops a job running rather than erroring. Use--verbose --dry-runto see how each name is classified. - Use ordinary, portable filename characters for base names — letters, digits,
-and_mid-name are fine; avoid spaces and path separators.
Ignore rules
Two prefixes take a file out of play entirely — not synced, not run:
| Prefix | Applies to | Use |
|---|---|---|
_ | Any file or folder name | Draft a job in place before it goes
live; hold server-only files like _env.json. Drop the underscore to
go live. |
. | Dotfiles and dotfolders | Editor state, .git,
.DS_Store — never leaves your machine. |
The rule is by name, so an entire _scratch/ sub-folder is ignored wholesale — a
convenient scratch area inside the content root.
The secrets file — _env.json
Secrets live in _env.json at the content root. Because it starts with _ it is
never uploaded by the client: you place it on the server by hand (under
/srv/cronhoster), and the runner reads it to supply secret values to jobs. Keeping it out
of the synced tree keeps it out of your working folder's version control too. The exact delivery
mechanism is part of the open runtime & secrets question; the file's
name and location are settled. The Scripts reference shows it
in use.