# How Hot Reloading Works in gdext-nim: Configuration and Limitations

> Discover how hot reloading works in gdext-nim by enabling reloadable true. Learn about configuration steps and understand its limitations for efficient Godot development.

- Repository: [godot-nim 4+/gdext-nim](https://github.com/godot-nim/gdext-nim)
- Tags: internals
- Published: 2026-03-02

---

**Hot reloading in gdext-nim is enabled by setting `reloadable = true` in the `.gdextension` configuration, allowing Godot’s GDExtensionManager to unload and reload the shared library when the editor regains focus after a rebuild.**

gdext-nim is a Nim binding for Godot 4’s GDExtension API that supports hot reloading of native shared libraries during development. By marking an extension as reloadable in the configuration DSL, developers can iterate on Nim code without restarting the Godot editor. This article examines the implementation in the source code, the exact reload mechanism, and the critical limitations you must account for in production workflows.

## Enabling Hot Reloading in gdext-nim

The reload capability is controlled through the `.gdextension` file generated during the build process. According to the `godot-nim/gdext-nim` source code, two specific files handle this configuration: the DSL definition and the build configuration helper.

### The Configuration DSL

In `src/gdext/private/configdsl.nim`, the configuration DSL exposes the `reloadable` entry that writes the flag to the final INI file:

```nim
config.eval:
  entry_symbol = "init_library"
  compatibility_minimum = 4.6
  reloadable = true          # <─ enables hot-reload

```

### The Build Configuration Step

During the `configure` build step defined in `src/gdext/buildconf.nim`, the system automatically injects the reloadable flag into the configuration:

```nim
configuration.update(setting.updateMethod, "reloadable", "true")

```

This generates a `.gdextension` file containing:

```ini
[configuration]
entry_symbol = "init_library"
compatibility_minimum = 4.6
reloadable = true

```

When this file is present, Godot’s **GDExtensionManager** recognizes the library as eligible for hot reloading.

## The Hot Reloading Workflow

Once enabled, the reload process is triggered by Godot’s editor lifecycle rather than explicit Nim code.

### How Godot Triggers the Reload

Godot exposes the reload capability through `GDExtensionManager.reload_extension(path)`, which gdext-nim binds in `src/gdext/classes/gdgdextensionmanager.nim`:

```nim

# From gdgdextensionmanager.nim

proc reloadExtension*(extension: String): Error {.gdcall.}

```

When the editor window regains focus after a successful build, Godot automatically executes this method for any extension marked `reloadable = true`. As noted in the tutorial and development guide, you simply rebuild and focus the editor to trigger the update.

### What Happens During a Reload

The engine performs four distinct operations:

1. **Unload** the previously loaded shared library using the internal `unload_extension` binding.
2. **Load** the new library binary via `load_extension`.
3. **Re-register** all classes, methods, signals, and properties defined in Nim through the `init_library` entry point.
4. **Preserve** existing node instances while re-initializing their fields through the newly registered constructors.

## Limitations of gdext Hot Reloading

While hot reloading accelerates development, the implementation has specific constraints regarding state management and structural changes.

### Structural Fragility

Adding new classes or methods works reliably, but **removing classes, changing inheritance hierarchies, or altering exported property layouts** can leave the editor in an inconsistent state. The documentation advises a full editor restart if puzzling errors appear after such changes.

### Persistent Runtime State

Because the Nim runtime does not reset process memory during a reload, **module-level globals and static data persist across reloads**. You must manually re-initialize cached state in methods like `_ready` to avoid undefined behavior.

### Platform and Workflow Constraints

- **Editor focus requirement**: Godot checks for changes only when the editor window gains focus. If you remain in an external IDE, the reload waits until you switch back.
- **Windows file locks**: On Windows, the build script works around DLL locks by writing to a temporary file and renaming it, but occasional lock contention may still require a manual restart.
- **Shared library only**: Hot reloading requires dynamic library builds (`.so`, `.dll`, `.dylib`). Static builds cannot be hot-reloaded.

### Error Handling Limitations

If the new library fails to load (e.g., missing symbols), Godot logs an error but continues using the previously loaded version. This silent failure may hide problems until you manually restart the editor.

## Practical Implementation Examples

The following patterns demonstrate safe hot reloading practices based on the source code structure.

### Basic Configuration

A minimal `bootstrap.nim` entry point that generates a reloadable extension:

```nim
import gdext
import classes/gdMyClass  # Your {.gdsync.} classes

GDExtensionEntryPoint   # Generates the .gdextension file with reloadable = true

```

Build and reload:

```bash
gdextwiz build    # Compiles to libnim.so

# Focus Godot editor to trigger automatic reload

```

### Handling Persistent State

Reset module-level state after reloads by implementing initialization logic in `_ready`:

```nim
type MyClass* {.gdsync.} = ptr object of Node
  counter*: int = 0

method _ready(self: MyClass) {.gdsync.} =
  # Re-initialize after hot reload

  self.counter = 0
  print "State reset after reload"

```

### Forcing a Manual Reload

From GDScript, you can trigger a reload programmatically:

```gdscript
var manager = Engine.get_singleton("GDExtensionManager")
manager.reload_extension("res://my_extension.gdextension")

```

## Summary

- Enable hot reloading by setting `reloadable = true` in the configuration DSL (`src/gdext/private/configdsl.nim`), which `src/gdext/buildconf.nim` injects during the configure step.
- Godot’s `GDExtensionManager.reload_extension` unloads and reloads the shared library when the editor regains focus after a build.
- New classes and methods register automatically, but structural changes (removed classes, property layout changes) often require a full editor restart.
- Global variables and cached resources survive reloads; explicitly reset state in `_ready` methods.
- The feature works only with dynamic shared libraries and requires the editor window to receive focus to detect changes.

## Frequently Asked Questions

### How do I enable hot reloading in a gdext-nim project?

Set `reloadable = true` inside the `config.eval` block in your Nim source or rely on the default `GDExtensionEntryPoint` template, which generates a `.gdextension` file containing `reloadable = true`. Rebuild with `gdextwiz build` and focus the Godot editor to trigger the reload.

### Why does my gdext extension not reload after building?

Godot checks for file changes only when the editor window gains focus. If you stay in your IDE or terminal, the reload will not trigger until you switch back to the editor. Additionally, ensure your `.gdextension` file contains the `reloadable = true` flag and that you are building a dynamic shared library (not a static binary).

### Can I hot reload changes to class properties or inheritance in gdext-nim?

Adding properties or methods generally works, but removing classes, changing inheritance hierarchies, or altering the memory layout of exported properties can corrupt the editor state. If you encounter cryptic errors after such changes, save your work and restart the Godot editor completely.

### How do I handle global variables that persist across hot reloads?

Module-level globals in Nim survive hot reloads because the process memory is not reset. You must manually re-initialize any cached data or singletons in your class's `_ready` method or another initialization hook to ensure they match the newly loaded library's state.