{"id":20258671,"url":"https://github.com/47ng/fastify-cron","last_synced_at":"2025-08-22T03:32:33.510Z","repository":{"id":36965297,"uuid":"239551450","full_name":"47ng/fastify-cron","owner":"47ng","description":"Run cron jobs alongside your Fastify server 👷","archived":false,"fork":false,"pushed_at":"2023-03-06T08:57:21.000Z","size":1108,"stargazers_count":47,"open_issues_count":14,"forks_count":5,"subscribers_count":3,"default_branch":"next","last_synced_at":"2024-11-24T18:23:47.943Z","etag":null,"topics":["cron","cron-jobs","fastify","fastify-plugin"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/47ng.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["franky47"],"liberapay":"francoisbest","custom":["https://paypal.me/francoisbest?locale.x=fr_FR"]}},"created_at":"2020-02-10T15:58:15.000Z","updated_at":"2024-03-27T11:14:20.000Z","dependencies_parsed_at":"2024-06-18T17:06:09.877Z","dependency_job_id":"d3453a5a-b9ea-478a-acef-18ef21e00b35","html_url":"https://github.com/47ng/fastify-cron","commit_stats":{"total_commits":219,"total_committers":6,"mean_commits":36.5,"dds":"0.24200913242009137","last_synced_commit":"eb5ae26a2763861892116411736c990a50606f49"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":"47ng/typescript-library-starter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/47ng%2Ffastify-cron","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/47ng%2Ffastify-cron/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/47ng%2Ffastify-cron/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/47ng%2Ffastify-cron/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/47ng","download_url":"https://codeload.github.com/47ng/fastify-cron/tar.gz/refs/heads/next","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230554330,"owners_count":18244234,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cron","cron-jobs","fastify","fastify-plugin"],"created_at":"2024-11-14T11:10:26.863Z","updated_at":"2024-12-20T08:09:07.689Z","avatar_url":"https://github.com/47ng.png","language":"TypeScript","readme":"\u003ch1 align=\"center\"\u003e\u003ccode\u003efastify-cron\u003c/code\u003e\u003c/h1\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n[![NPM](https://img.shields.io/npm/v/fastify-cron?color=red)](https://www.npmjs.com/package/fastify-cron)\n[![MIT License](https://img.shields.io/github/license/47ng/fastify-cron.svg?color=blue)](https://github.com/47ng/fastify-cron/blob/master/LICENSE)\n[![Continuous Integration](https://github.com/47ng/fastify-cron/workflows/Continuous%20Integration/badge.svg?branch=next)](https://github.com/47ng/fastify-cron/actions)\n[![Coverage Status](https://coveralls.io/repos/github/47ng/fastify-cron/badge.svg?branch=next)](https://coveralls.io/github/47ng/fastify-cron?branch=next)\n\n\u003c/div\u003e\n\n\u003cp align=\"center\"\u003e\n  Run \u003ca href=\"https://www.npmjs.com/package/cron\"\u003ecron\u003c/a\u003e jobs alongside your \u003ca href=\"https://www.fastify.io\"\u003eFastify\u003c/a\u003e server.\n\u003c/p\u003e\n\n\u003cbr/\u003e\n\nWhile running cron jobs in the same process as a service is not the best\nrecommended practice (according to the [Twelve Factor App](https://12factor.net/processes)),\nit can be useful when prototyping and when implementing low-criticality features\non single-instance services (remember that when scaling horizontally, all your\njobs may run in parallel too, see [Scaling](#scaling)).\n\nThere is an existing discussion about this in [`fastify/fastify#1312`](https://github.com/fastify/fastify/issues/1312).\n\n## Installation\n\n```shell\n$ yarn add fastify-cron\n# or\n$ npm i fastify-cron\n```\n\n## Usage\n\nRegister the plugin with your Fastify server, and define a list of jobs to be\ncreated:\n\n\u003e _If (like me) you always forget the syntax for cron times,\n\u003e check out [crontab.guru](https://crontab.guru/)._\n\n```ts\nimport Fastify from 'fastify'\n\n// Import it this way to benefit from TypeScript typings\nimport fastifyCron from 'fastify-cron'\n\nconst server = Fastify()\n\nserver.register(fastifyCron, {\n  jobs: [\n    {\n      // Only these two properties are required,\n      // the rest is from the node-cron API:\n      // https://github.com/kelektiv/node-cron#api\n      cronTime: '0 0 * * *', // Everyday at midnight UTC\n\n      // Note: the callbacks (onTick \u0026 onComplete) take the server\n      // as an argument, as opposed to nothing in the node-cron API:\n      onTick: async server =\u003e {\n        await server.db.runSomeCleanupTask()\n      }\n    }\n  ]\n})\n\nserver.listen(() =\u003e {\n  // By default, jobs are not running at startup\n  server.cron.startAllJobs()\n})\n```\n\nYou can create other jobs later with `server.cron.createJob`:\n\n```ts\nserver.cron.createJob({\n  // Same properties as above\n  cronTime: '0 0 * * *', // Everyday at midnight UTC\n  onTick: () =\u003e {}\n})\n```\n\nTo interact with your jobs during the lifetime of your server, you can give\nthem names:\n\n```ts\nserver.cron.createJob({\n  name: 'foo',\n  cronTime: '0 * * * *', // Every hour at X o'clock\n  onTick: () =\u003e {}\n})\n\n// Later on, retrieve the job:\nconst fooJob = server.cron.getJobByName('foo')\nfooJob.start()\n```\n\nOtherwise, you can access the list of jobs ordered by order of creation\nat `server.cron.jobs`.\n\n\u003e **Warning**: if you mutate that list, you must take responsibility for manually\n\u003e shutting down the jobs you pull out.\n\n## Cron Jobs Lifecycle\n\nCron jobs can be created either by passing properties to the `job` option when\nregistering the plugin, or when explicitly calling `server.cron.createJob`.\n\nThey are created by default in a stopped state, and are not automatically\nstarted (one good place to do so would be in a post-listening hook, but\nFastify does not provide one).\n\n### Starting jobs\n\nThe recommended moment to start your jobs is when the server is listening\n(this way you can create test servers without cron jobs running around) :\n\n```ts\nconst server = Fastify()\n\nserver.register(fastifyCron, {\n  jobs: [\n    // ...\n  ]\n})\n\nserver.listen(() =\u003e {\n  server.cron.startAllJobs()\n})\n```\n\nIf you want to start a job immediately (synchronously) after its creation,\nset the `start` property to `true` (this is part of\nthe [`cron` API](https://github.com/kelektiv/node-cron#api)):\n\n```ts\n// When registering the plugin:\nserver.register(fastifyCron, {\n  jobs: [\n    {\n      cronTime: '0 0 * * *',\n      onTick: () =\u003e {},\n      start: true // Start job immediately\n    }\n  ]\n})\n\n// You can also act directly on the job object being returned:\nconst job = server.cron.createJob({ cronTime: '0 0 * * *', onTick: () =\u003e {} })\njob.start()\n```\n\nIf your job callback needs the server to be ready (all plugins loaded), it can\nbe inappropriate to start the job straight away. You can have it start\nautomatically when the server is ready by settings the `startWhenReady`\nproperty to `true`:\n\n```ts\nserver.register(fastifyCron, {\n  jobs: [\n    {\n      name: 'foo',\n      cronTime: '0 0 * * *',\n      onTick: server =\u003e {\n        server.db.doStruff()\n      },\n      startWhenReady: true\n    }\n  ]\n})\n```\n\n### Stopping jobs\n\nJobs are stopped automatically when the server stops, in an `onClose` hook.\n\nIf you have running cron jobs and need to stop them all (eg: in a test\nenvironment where the server is not listening):\n\n```ts\ntest('some test', () =\u003e {\n  // ...\n\n  // Stop all cron jobs to let the test runner exit cleanly:\n  server.cron.stopAllJobs()\n})\n```\n\n## Scaling\n\nWhen horizontal-scaling your applications (running multiple identical instances\nin parallel), you'll probably want to make sure only one instance runs the cron\ntasks.\n\nIf you have a way to uniquely identify an instance (eg: a number passed in the\nenvironment), you could use that to only enable crons for this instance.\n\nExample for [Clever Cloud](https://www.clever-cloud.com/doc/develop/env-variables/#what-is-the-instance_number-variable-used-for):\n\n```ts\nif (process.env.INSTANCE_NUMBER === 0) {\n  server.register(fastifyCron, {\n    jobs: [\n      // ...\n    ]\n  })\n}\n```\n\n## Conditionally running jobs\n\nYou may want to run certain jobs in development only, or under other conditions.\n\n`fastify-cron` will ignore any falsy values in the `jobs` array, so you can do:\n\n```ts\nserver.register(fastifyCron, {\n  jobs: [\n    process.env.ENABLE_DEV_JOB === 'true' \u0026\u0026 {\n      name: 'devJob',\n      cronTime: '* * * * *',\n      onTick: server =\u003e {\n        // ...\n      }\n    }\n  ]\n})\n```\n\n## Compatibility Notes\n\nSome compatibility issues may arise with the [`cron` API](https://github.com/kelektiv/node-cron#api).\n\nPossible issues (ticked if confirmed and unhandled):\n\n- [ ] Adding callbacks to a job via `addCallback` may not result in the server being passed as an argument\n- [ ] Using `fireOnTick` may lead to the same problem\n\n## License\n\n[MIT](https://github.com/47ng/fastify-cron/blob/master/LICENSE) - Made with ❤️ by [François Best](https://francoisbest.com)\n\nUsing this package at work ? [Sponsor me](https://github.com/sponsors/franky47) to help with support and maintenance.\n","funding_links":["https://github.com/sponsors/franky47","https://liberapay.com/francoisbest","https://paypal.me/francoisbest?locale.x=fr_FR"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F47ng%2Ffastify-cron","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F47ng%2Ffastify-cron","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F47ng%2Ffastify-cron/lists"}