{"id":19411933,"url":"https://github.com/artsy/express-reloadable","last_synced_at":"2025-04-24T10:34:17.208Z","repository":{"id":25694697,"uuid":"100528409","full_name":"artsy/express-reloadable","owner":"artsy","description":"Automatically hot-swap Express server code without the restart","archived":false,"fork":false,"pushed_at":"2024-01-23T21:31:47.000Z","size":208,"stargazers_count":26,"open_issues_count":8,"forks_count":4,"subscribers_count":38,"default_branch":"master","last_synced_at":"2025-04-19T15:13:09.759Z","etag":null,"topics":["developer-tools","express","hot-swap"],"latest_commit_sha":null,"homepage":"http://artsy.github.io/blog/2017/12/05/Express-Reloadable-Update/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/artsy.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"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}},"created_at":"2017-08-16T20:08:31.000Z","updated_at":"2023-12-09T22:43:46.000Z","dependencies_parsed_at":"2024-01-23T22:44:07.112Z","dependency_job_id":null,"html_url":"https://github.com/artsy/express-reloadable","commit_stats":{"total_commits":97,"total_committers":9,"mean_commits":"10.777777777777779","dds":0.6907216494845361,"last_synced_commit":"914f6bb34d04b13e5393f55ddfb36d22e22b4537"},"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artsy%2Fexpress-reloadable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artsy%2Fexpress-reloadable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artsy%2Fexpress-reloadable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artsy%2Fexpress-reloadable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/artsy","download_url":"https://codeload.github.com/artsy/express-reloadable/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250609325,"owners_count":21458468,"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":["developer-tools","express","hot-swap"],"created_at":"2024-11-10T12:23:51.342Z","updated_at":"2025-04-24T10:34:16.927Z","avatar_url":"https://github.com/artsy.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @artsy/express-reloadable\n\nWhen developing a Node app it's common to rely on tools like [`node-dev`](https://github.com/fgnass/node-dev) or [`nodemon`](https://github.com/remy/nodemon) to make the development process more rapid by automatically restarting the server instance on file-change. What `express-reloadable` does is listen for source-code changes within a subset of your app and, scanning Node's internal module cache, clears the `require` call if found. This tricks Node into thinking the module has not yet been loaded, effectively hot-swapping out your code without a full restart. Additionally, when the `watchModules` option is passed, `express-reloadable` will listen for changes to NPM module code and reload on change. Useful when working with `yarn link` across packages / repos. Crazy-fast development speed!\n\n\u003e **Disclaimer**: While this works for most of our use-cases, this is an example of \"`require hacking\"` and hasn't been tested in all environments. Your mileage may vary.\n\n**How it works**:\n- `express-reloadable` is called with a path to an app, which it then mounts\n- When source-code within that folder / app changes an internal lookup is made to Node, scanning its `require` cache for the changed file\n- If found, it is cleared internally via `delete require.cache[id]`\n- When a new request is made `express-reloadable` executes a callback that re-requires the code and changes are instantly available.\n\n**Installation**:\n\n```sh\nyarn add @artsy/express-reloadable\n```\n\n**Example**:\n\nThe below example assumes that the folders `/api` and `/client` exist, and that each contain an index file that exports a mountable express.js route.\n\n```js\nimport express from 'express'\nimport { createReloadable, isDevelopment } from '@artsy/express-reloadable'\n\nconst app = express()\n\nif (isDevelopment) {\n\n  // Pass in `app` and current `require` context\n  const mountAndReload = createReloadable(app, require)\n\n  // Pass in the path to an express sub-app and everything is taken care of\n  mountAndReload(path.resolve(__dirname, './client'))\n\n  // Full example:\n  app.use('/api', mountAndReload(path.resolve(__dirname, './api')), {\n\n    // If you need to mount an app at a particular root (`/api`), pass in\n    // `mountPoint` as an option.\n    mountPoint: '/api',\n\n    // Or if you're using `yarn link` (or npm) to symlink external dependencies\n    // during dev, pass in an array of modules to watch. Changes made internally\n    // will be instantly available in the app. Additionally, using something like \n    // `glob`, other modules outside of express route path can be passed.\n    watchModules: [\n      '@artsy/reaction',\n      '@artsy/artsy-xapp'\n    ]\n  }))\n\n  // If prod, mount apps like normal\n} else {\n  app.use('/api', require('./api')\n  app.use(require('./client')\n}\n\napp.listen(3000, () =\u003e {\n  console.log(`Listening on port 3000`)\n})\n```\n\n**Troubleshooting**:\n\n\u003e Help! I've mounted my app using reloadable but I'm not seeing any changes?\n\nFor the utility to work you need to a) ensure that `NODE_ENV=development` (for safety) and b) the path to your app is absolute:\n\n```js\n// Incorrect\napp.use(reloadAndMount('./path/to/app'))\n\n// Correct \napp.use(reloadAndMount(path.resolve(__dirname, 'path/to/app')))\n```\n\n**Thanks**:\n\nThis package was heavily inspired by @glenjamin's [ultimate-hot-loading-example](https://github.com/glenjamin/ultimate-hot-reloading-example).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fartsy%2Fexpress-reloadable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fartsy%2Fexpress-reloadable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fartsy%2Fexpress-reloadable/lists"}