diff --git a/Makefile b/Makefile
index 4fa275a1b338a5..c8a22908b534cb 100644
--- a/Makefile
+++ b/Makefile
@@ -294,6 +294,7 @@ coverage-report-js: ## Report JavaScript coverage results.
cctest: all ## Run the C++ tests using the built `cctest` executable.
@out/$(BUILDTYPE)/$@ --gtest_filter=$(GTEST_FILTER)
$(NODE) ./test/embedding/test-embedding.js
+ $(NODE) ./test/sqlite/test-sqlite-extensions.mjs
.PHONY: list-gtests
list-gtests: ## List all available C++ gtests.
@@ -574,6 +575,7 @@ test-ci: | clear-stalled bench-addons-build build-addons build-js-native-api-tes
--mode=$(BUILDTYPE_LOWER) --flaky-tests=$(FLAKY_TESTS) \
$(TEST_CI_ARGS) $(CI_JS_SUITES) $(CI_NATIVE_SUITES) $(CI_DOC)
$(NODE) ./test/embedding/test-embedding.js
+ $(NODE) ./test/sqlite/test-sqlite-extensions.mjs
$(info Clean up any leftover processes, error if found.)
ps awwx | grep Release/node | grep -v grep | cat
@PS_OUT=`ps awwx | grep Release/node | grep -v grep | awk '{print $$1}'`; \
@@ -1432,6 +1434,7 @@ LINT_CPP_FILES = $(filter-out $(LINT_CPP_EXCLUDE), $(wildcard \
test/cctest/*.h \
test/embedding/*.cc \
test/embedding/*.h \
+ test/sqlite/*.c \
test/fixtures/*.c \
test/js-native-api/*/*.cc \
test/node-api/*/*.cc \
diff --git a/doc/api/errors.md b/doc/api/errors.md
index f66cebd088ae4c..f2bfa7e087f4ec 100644
--- a/doc/api/errors.md
+++ b/doc/api/errors.md
@@ -2172,6 +2172,16 @@ added:
An ESM loader hook returned without calling `next()` and without explicitly
signaling a short circuit.
+
+
+### `ERR_LOAD_SQLITE_EXTENSION`
+
+
+
+An error occurred while loading a SQLite extension.
+
### `ERR_MEMORY_ALLOCATION_FAILED`
diff --git a/doc/api/permissions.md b/doc/api/permissions.md
index a03285e28641e8..d03913e7858d66 100644
--- a/doc/api/permissions.md
+++ b/doc/api/permissions.md
@@ -147,6 +147,8 @@ There are constraints you need to know before using this system:
flags that can be set via runtime through `v8.setFlagsFromString`.
* OpenSSL engines cannot be requested at runtime when the Permission
Model is enabled, affecting the built-in crypto, https, and tls modules.
+* Run-Time Loadable Extensions cannot be loaded when the Permission Model is
+ enabled, affecting the sqlite module.
* Using existing file descriptors via the `node:fs` module bypasses the
Permission Model.
diff --git a/doc/api/sqlite.md b/doc/api/sqlite.md
index cdf5d690521a06..29d9525d6ea4d8 100644
--- a/doc/api/sqlite.md
+++ b/doc/api/sqlite.md
@@ -108,6 +108,10 @@ added: v22.5.0
[double-quoted string literals][]. This is not recommended but can be
enabled for compatibility with legacy database schemas.
**Default:** `false`.
+ * `allowExtension` {boolean} If `true`, the `loadExtension` SQL function
+ and the `loadExtension()` method are enabled.
+ You can call `enableLoadExtension(false)` later to disable this feature.
+ **Default:** `false`.
Constructs a new `DatabaseSync` instance.
@@ -120,6 +124,30 @@ added: v22.5.0
Closes the database connection. An exception is thrown if the database is not
open. This method is a wrapper around [`sqlite3_close_v2()`][].
+### `database.loadExtension(path)`
+
+
+
+* `path` {string} The path to the shared library to load.
+
+Loads a shared library into the database connection. This method is a wrapper
+around [`sqlite3_load_extension()`][]. It is required to enable the
+`allowExtension` option when constructing the `DatabaseSync` instance.
+
+### `database.enableLoadExtension(allow)`
+
+
+
+* `allow` {boolean} Whether to allow loading extensions.
+
+Enables or disables the `loadExtension` SQL function, and the `loadExtension()`
+method. When `allowExtension` is `false` when constructing, you cannot enable
+loading extensions for security reasons.
+
### `database.exec(sql)`