diff --git a/CHANGELOG.md b/CHANGELOG.md
index 66e02304..1506de11 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,7 @@
* Add `exe=@ENV` preference to read `JULIA_PYTHONCALL_EXE` without loading CondaPkg.
* Improved TTFX in JuliaCall.
* Minimum supported Python version is now 3.11.
+* JuliaCall option `compiled_modules` now accepts `existing` and `strict` (Julia 1.11+).
## 0.9.37 (2026-10-12)
* Compatibility fix with Python 3.15 from conda-forge, which no longer bundles libpython.
diff --git a/docs/src/juliacall.md b/docs/src/juliacall.md
index 84bdae00..11cb9333 100644
--- a/docs/src/juliacall.md
+++ b/docs/src/juliacall.md
@@ -127,7 +127,7 @@ be configured in two ways:
| `-X juliacall-home=
` | `PYTHON_JULIACALL_BINDIR=` | The directory containing the julia executable. |
| `-X juliacall-check-bounds=` | `PYTHON_JULIACALL_CHECK_BOUNDS=` | Enable or disable bounds checking. |
| `-X juliacall-compile=` | `PYTHON_JULIACALL_COMPILE=` | Enable or disable JIT compilation. |
-| `-X juliacall-compiled-modules=` | `PYTHON_JULIACALL_COMPILED_MODULES=` | Enable or disable incrementally compiling modules. |
+| `-X juliacall-compiled-modules=` | `PYTHON_JULIACALL_COMPILED_MODULES=` | Enable or disable incrementally compiling modules (`existing`, `strict`: Julia 1.11+). |
| `-X juliacall-depwarn=` | `PYTHON_JULIACALL_DEPWARN=` | Enable or disable deprecation warnings. |
| `-X juliacall-handle-signals=` | `PYTHON_JULIACALL_HANDLE_SIGNALS=` | Enable or disable Julia signal handling. |
| `-X juliacall-inline=` | `PYTHON_JULIACALL_INLINE=` | Enable or disable inlining. |
diff --git a/pysrc/juliacall/__init__.py b/pysrc/juliacall/__init__.py
index 9370b60d..4b27810e 100644
--- a/pysrc/juliacall/__init__.py
+++ b/pysrc/juliacall/__init__.py
@@ -195,7 +195,7 @@ def args_from_config(config):
CONFIG['opt_compile'] = choice('compile', ['yes', 'no', 'all', 'min'])[0]
CONFIG["opt_trace_compile"] = option('trace_compile')[0]
CONFIG["opt_trace_compile_timing"] = flag('trace_compile_timing')[0]
- CONFIG['opt_compiled_modules'] = choice('compiled_modules', ['yes', 'no'])[0]
+ CONFIG['opt_compiled_modules'] = choice('compiled_modules', ['yes', 'no', 'existing', 'strict'])[0]
CONFIG['opt_depwarn'] = choice('depwarn', ['yes', 'no', 'error'])[0]
CONFIG['opt_inline'] = choice('inline', ['yes', 'no'])[0]
CONFIG['opt_min_optlevel'] = choice('min_optlevel', ['0', '1', '2', '3'])[0]
diff --git a/pytest/test_all.py b/pytest/test_all.py
index 151a7361..8ceaf9df 100644
--- a/pytest/test_all.py
+++ b/pytest/test_all.py
@@ -199,3 +199,33 @@ def test_call_nogil(yld, raw):
t2 = time() - t0
# executing the tasks should take about 1 second because they happen in parallel
assert 0.9 < t2 < 1.5
+
+
+@pytest.mark.parametrize("mode,value", [("existing", 2), ("strict", 3)])
+def test_compiled_modules_option(mode, value):
+ import os
+ import subprocess
+ import sys
+
+ from juliacall import Main as jl
+
+ if jl.seval("VERSION < v\"1.11\""):
+ pytest.skip("--compiled-modules=existing/strict requires Julia 1.11")
+ # the parent process has loaded PythonCall, so its cache files exist for the
+ # same flags (the child inherits PYTHON_JULIACALL_*) and it can load them without compiling
+ env = os.environ.copy()
+ env["PYTHON_JULIACALL_COMPILED_MODULES"] = mode
+ result = subprocess.run(
+ [
+ sys.executable,
+ "-c",
+ "from juliacall import Main as jl;"
+ " print(jl.seval('Base.JLOptions().use_compiled_modules'), end='')",
+ ],
+ env=env,
+ capture_output=True,
+ text=True,
+ timeout=180,
+ )
+ assert result.returncode == 0, result.stderr
+ assert result.stdout == str(value)