Hot-Reload for Obsidian: watching main.js so you stop restarting the app
Automatically reload Obsidian plugins in development when their files are changed
At a glance
- What is it?
- Hot-Reload is an Obsidian plugin that watches the main.js and styles.css of plugins you are developing and disables then re-enables them once your build settles, with an opt-in marker per plugin and desktop-first support.
- Who is it for?
- Hot-Reload earns a place in a desktop Obsidian plugin developer's vault when you rebuild main.js locally and want the change live without touching the settings panel, and the opt-in model keeps it from touching plugins you did not mark. It is the wrong choice for end users, since it can enable plugins that are not enabled, and its mobile support is still beta and limited to Obsidian 1.6.7 and up.
- Can I use it commercially?
- Yes. ISC is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 109 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The reload dance every Obsidian plugin developer knows
Obsidian plugins do not hot reload on their own. If you are writing one and you rebuild main.js, the running app keeps the old code until you either restart Obsidian or go into the plugin settings, disable the plugin, and enable it again. The README names both routes as the familiar friction this project removes.
Hot-Reload installs into Obsidian itself, as an ordinary community plugin, and then watches the plugins you are working on. When a watched file changes, the plugin disables and re-enables the target plugin for you. A notice appears briefly in Obsidian when the reload happens, and the verbose logs in the developer tools reflect the reload too, so you get some confirmation that something happened rather than watching a screen that may or may not have updated.
The audience is narrow and the README says so plainly: you do not need this unless you are developing plugins of your own. That is not politeness, it is a warning. The plugin can enable plugins that are not currently enabled in the settings, so installing it on a vault you use for reading is a decision with consequences.
Opt-in markers decide which plugins are watched
Automatic watching needs a boundary, and this project draws it with two markers. A plugin directory is watched if it contains a .git subdirectory or a file called .hotreload. That covers the common case of a plugin you have checked out with git, and it covers the case of a plugin folder that is not under version control, where you drop in an empty .hotreload file to opt in.
Within a watched directory, the plugin watches main.js and styles.css, which are the two files Obsidian actually loads.
The watch list is maintained automatically as well. The README states that the plugin also watches for changes to manifest.json files, and for the addition or removal of .git or .hotreload, and updates its watch lists accordingly. The consequence is that there is no configuration to edit: adding a plugin to the hot reload list means putting it under revision control or creating a .hotreload file in it, and removing it means undoing that.
There is a neat detail in how the marker stays local. Obsidian only includes main.js and styles.css in plugin downloads, so a .hotreload file cannot escape into the wild when someone installs your plugin from the marketplace. Someone else using Hot-Reload will not suddenly start reloading your plugin.
The three-quarter second delay is what makes it usable with a bundler
Reload happens once changes have stopped for about three-quarters of a second. That number is the design decision that makes the plugin practical rather than annoying.
A typical build writes several files, sometimes in stages, and a watcher that reacted to the first byte would reload a half written bundle. The delay means the plugin fires after the build has settled, once.
It also means the plugin is deliberately not a file watcher for arbitrary code. It reacts to completed writes to main.js and styles.css, and nothing else in the plugin directory is a trigger. If your build writes to an intermediate file and then copies it into place, the copy is what counts, and the timing still works because the copy is the last write.
The cost of the same design is that you cannot tune it. The README documents no setting for the delay, so a build that writes files slowly, for example emitting chunks over several seconds, can reload more than once, and a build that writes nothing to main.js will not reload at all.
Installing into a vault by hand
This is an Obsidian plugin like any other, so the install path is the standard one. The README says it must be installed from Obsidian's settings, or cloned into your vault's .obsidian/plugins/ directory, or into a similar directory if you have overridden the .obsidian directory name in the Obsidian settings. Once the files are in place, you enable it in Obsidian's Community Plugins settings.
For a developer who has the repository checked out, the practical route is to build the plugin and place the built files where Obsidian expects them. The repository is a JavaScript project with a package.json that declares two scripts:
"dev": "node ophidian.config.mjs dev",
"build": "node ophidian.config.mjs production"Both run through ophidian.config.mjs, with the mode as an argument, and the build is driven by the @ophidian/build dependency declared in devDependencies. The same file lists obsidian and monkey-around as the other development dependencies, and the project pins pnpm as its package manager with pnpm-lock.yaml in the tree, so a pnpm based workflow is what the repository expects.
The repository root holds hot-reload.ts as the TypeScript source alongside main.js, plus manifest.json and versions.json, which are the files Obsidian reads to know the plugin's identity and supported app versions.
Directory symlinks work, file symlinks do not
If your plugin build lives somewhere other than the vault, the README says Hot-Reload supports directory symlinks, so you can have a plugin folder that symlinks to your build output. It also suggests doing it the other way around instead, linking the build output into the plugin directory, with the example given as:
ln -s /some/Vault/.obsidian/plugins/my-plugin ./distThat direction puts a symlink to the vault's plugin folder inside your dist directory, so your builder writes into the dev or test vault without a copy step.
The limit is explicit: file symlinks are not supported. The plugin watches files inside a plugin directory, and a symlinked file is not handled the same way as a real one, so a build that symlinks individual output files into place will not trigger a reload the way a directory symlink does.
For most plugin builds, which emit a bundle into a directory, that constraint rarely bites. It matters if your bundler is configured to symlink individual chunks, in which case you want the directory level link.
Mobile support is beta and double reloading is a real failure mode
The plugin was designed for the desktop. Mobile support was added in 0.3.0 and the README describes it as still in experimental or beta status, supporting only Obsidian 1.6.7 and up. That is a narrow surface to depend on.
There is a specific trap here, and the README spells it out. If you use Obsidian Sync, you can enable the setting for Sync, Vault configuration sync, Installed community plugins, so that Obsidian restarts modified plugins after a sync. The tip comes from a community member, and the caveat is that if you do this you should not enable Hot-Reload on the mobile device, or you will get double reloading of changed plugins.
The alternative given is a separate plugin, Hot Reload Mobile, which works with any synchronization mechanism that updates notes by writing to a note on the desktop to trigger the reload on the mobile side after the note syncs. That is a different design: instead of watching files on the device, it uses a note as a signal channel through whatever sync tool you already use.
Two reload mechanisms watching the same change is exactly the kind of setup that produces confusing behaviour, so on mobile the sensible reading of the README is to pick one mechanism per device.
Reload does not replace cleaning up in onunload
The README is direct about the boundary of responsibility: while this plugin takes care of the reload grunt work, it is your plugin's job to clean up after itself. If you are not making good use of onunload() and the various registerX() methods to ensure your changes unload properly, you may leave Obsidian in an unstable state and be forced to restart or reload the app to restore it.
That is a fair division. Hot-Reload performs the disable and re-enable sequence. What a plugin registers, whether an interval, an event handler, a DOM mutation observer or a workspace listener, has to be undone by the plugin, in the same way it would be if a user toggled the plugin off by hand.
There is one behaviour that cuts in your favour. Because the plugin can enable plugins that are not currently enabled, as long as they are checked out with git or have a .hotreload file, a plugin whose load process broke can be brought back by saving the file again. The README describes this as a genuine benefit during development, since a broken load no longer forces you back to the settings panel.
Releases, licensing and the cost of staying current
The project publishes numbered releases rather than tags with a scheme you have to decode. Version 0.3.1 is dated 2026-07-06, 0.3.0 on 2025-08-14, and 0.2.2 on 2025-07-14. The repository is not archived, and the last push was on 2026-07-06.
The release history carries its own information. The most recent tagged versions are 0.3.1 on 2026-07-06 and 0.3.0 on 2025-08-14, with 0.2.2 on 2025-07-14 before it, and 0.3.0 is the release that added the experimental mobile support. If you depend on the mobile path, you are on the newest release and on a beta feature, which is a combination worth planning around.
The licence is ISC, and the same identifier appears in the package.json license field. It is a short permissive licence, and the practical question for a plugin like this one is less about redistribution than about the fact that it runs inside a user's vault with access to that vault's data and the ability to enable other plugins.
Editorial conclusion
Hot-Reload earns a place in a desktop Obsidian plugin developer's vault when you rebuild main.js locally and want the change live without touching the settings panel, and the opt-in model keeps it from touching plugins you did not mark. It is the wrong choice for end users, since it can enable plugins that are not enabled, and its mobile support is still beta and limited to Obsidian 1.6.7 and up. Before you enable it, check two things in your own vault: that the plugin directories you want watched contain a .git subdirectory or a .hotreload file, and that your own plugin cleans up in onunload() and its registerX() calls, because Hot-Reload reloads the plugin but will not repair an unclean unload.
Frequently asked questions
How do I install the Hot-Reload plugin for Obsidian?
Install it from Obsidian's settings, or clone it into your vault's .obsidian/plugins/ directory (or the equivalent if you renamed that directory), then enable it in Obsidian's Community Plugins settings. The README notes it is for plugin developers only, because it can enable other plugins.
How does Hot-Reload decide which Obsidian plugins to watch?
A plugin directory is watched when it contains a .git subdirectory or a .hotreload file. Within it, main.js and styles.css are watched, and the plugin also tracks changes to manifest.json and the addition or removal of the markers, so no configuration is needed.
Does Hot-Reload support symlinks for Obsidian plugin builds?
Directory symlinks are supported, for example ln -s /some/Vault/.obsidian/plugins/my-plugin ./dist to make a builder write into a dev or test vault. File symlinks are not supported.
Can I use Hot-Reload on Obsidian mobile?
Mobile support was added in 0.3.0 and is still in experimental or beta status, supporting Obsidian 1.6.7 and up. The README warns against enabling Hot-Reload on mobile while also using Obsidian Sync for vault configuration and installed community plugins, since that causes double reloading.
Why does Obsidian become unstable after a hot reload?
The README states that cleanup is the responsibility of your own plugin: if you are not making good use of onunload() and the various registerX() methods, Obsidian can be left in an unstable state that forces a restart. Hot-Reload performs the disable and re-enable, not the cleanup.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/pjeby-hot-reload)Was this useful?