Missing FTS3 Module in SQLite WASM Builds: Causes and Solutions

Issue Overview: FTS3 Module Unavailable in SQLite WASM Builds

The core issue revolves around the inability to create virtual tables using the FTS3 (Full-Text Search version 3) module in SQLite when using WebAssembly (WASM) builds, specifically version 3.47.0-build1 or newer. Attempting to execute a CREATE VIRTUAL TABLE statement with USING fts3 results in the error SQLITE_ERROR: no such module: fts3. This contradicts the expectation set by SQLite’s official documentation, which states that FTS3 and FTS4 are included in "all builds" of SQLite. However, this documentation applies specifically to C-language builds, not WASM builds. The WASM distribution of SQLite, designed for browser and JavaScript environments, has historically excluded FTS3 by default, favoring its successor, FTS5, which offers improved performance, features, and maintenance.

The confusion arises from discrepancies between platform-specific build configurations and the generalization of documentation. FTS3, while still supported in C builds for backward compatibility, is considered obsolete. WASM builds were introduced long after FTS5 became the recommended full-text search solution. Consequently, FTS3 was never enabled in the canonical WASM builds distributed by the SQLite team. Community-maintained WASM builds, such as those published via npm (@sqlite.org/sqlite-wasm), may include FTS3 if custom build flags were applied during compilation. However, the official SQLite WASM builds explicitly disable FTS3 to reduce binary size and avoid redundancy with FTS5.

Users migrating from older WASM builds (e.g., 3.45.1-build1) might encounter this issue if they previously relied on FTS3 in a community-maintained build where FTS3 was enabled. The problem is exacerbated by the lack of clear documentation distinguishing between build targets (C vs. WASM) and their respective module inclusions. This creates a mismatch between user expectations and the actual capabilities of the WASM runtime.

Possible Causes: Why FTS3 Is Missing in SQLite WASM Builds

1. Intentional Exclusion of FTS3 in Canonical WASM Builds

The SQLite development team has deliberately excluded FTS3 from WASM builds to prioritize modern alternatives. FTS5, introduced in SQLite 3.9.0 (2015), supersedes FTS3/FTS4 with enhanced query syntax, performance optimizations, and support for custom tokenizers. Since WASM support was added to SQLite much later (circa 2020), there was no need to include obsolete modules like FTS3 in a platform targeting modern applications. The WASM build system is configured with minimalistic defaults, omitting legacy modules unless explicitly enabled.

2. Community-Maintained Builds with Custom Flags

Third-party distributions of SQLite WASM, such as the npm package @sqlite.org/sqlite-wasm, may include FTS3 if the maintainer applied custom compile-time flags. For example, prior to version 3.41.0, some WASM builds inadvertently included FTS4 due to a misinterpretation of its dependency on FTS5. This led to temporary availability of FTS4 in older WASM builds, which could be mistaken for FTS3 support. Community maintainers might also enable FTS3 for compatibility with legacy applications, but such builds are not officially endorsed by the SQLite team.

3. Documentation Ambiguity Between Build Targets

SQLite’s documentation for FTS3/FTS4 states that these modules are included in "all builds," but this applies only to C-language distributions. The WASM build process uses a separate configuration file (ext/wasm/GNUmakefile) that explicitly enables FTS5 while omitting FTS3. Users unaware of this distinction may assume WASM builds inherit the same module set as C builds, leading to unexpected errors.

4. Version-Specific Build Flag Changes

Between SQLite WASM releases, build flags may change, altering module availability. For instance, in version 3.40.0, FTS4 was briefly enabled due to a misunderstanding about its relationship with FTS5. This was corrected in 3.41.0, removing FTS4. Users upgrading from older WASM builds (e.g., 3.45.1) to newer versions (e.g., 3.47.0) might lose access to FTS3/4 if they were relying on a community build that previously included them.

Troubleshooting Steps, Solutions & Fixes: Resolving FTS3 Issues in WASM Builds

Step 1: Verify SQLite Build Configuration and Module Availability

Before modifying code or build processes, confirm whether the current SQLite WASM build includes FTS3. Execute the following SQL commands to list available modules and compile-time options:

-- Check enabled FTS modules (if any)
SELECT * FROM sqlite_schema WHERE type = 'table' AND name LIKE '%fts%';

-- List compile-time options
PRAGMA compile_options;

If the output of PRAGMA compile_options does not include ENABLE_FTS3 or ENABLE_FTS4, the build excludes these modules. For example, canonical WASM builds will show ENABLE_FTS5 but not ENABLE_FTS3.

Step 2: Migrate from FTS3 to FTS5

Since FTS3 is unavailable in official WASM builds, refactor existing schemas and queries to use FTS5. The migration involves:

A. Schema Modification

Replace USING fts3 with USING fts5 in CREATE VIRTUAL TABLE statements. For example:

-- Original FTS3 table
CREATE VIRTUAL TABLE example USING fts3(text, tokenize=porter);

-- Migrated to FTS5
CREATE VIRTUAL TABLE example USING fts5(text, tokenize=porter);

B. Query Syntax Adjustments

FTS5 introduces minor syntax differences:

  • Phrase queries: Use double quotes ("...") instead of FTS3’s curly braces ({...}).
  • Column filters: Specify columns with column:term instead of column:term (no change, but be aware of parser differences).
  • Boolean operators: FTS5 requires explicit use of AND, OR, and NOT instead of implicit spaces as AND operators.

Example FTS5 query:

SELECT * FROM example WHERE example MATCH 'text:important AND NOT deprecated';

C. Tokenizer Compatibility

The porter tokenizer (stemming) is available in both FTS3 and FTS5. However, custom tokenizers require reimplementation using the FTS5 API.

Step 3: Rebuild SQLite WASM with FTS3 Enabled (Advanced)

If migrating to FTS5 is impractical, compile a custom WASM build with FTS3 enabled. This requires:

A. Setting Up the SQLite Build Environment

  1. Clone the SQLite source tree:

    fossil clone https://www.sqlite.org/src sqlite.fossil
    mkdir sqlite && cd sqlite
    fossil open ../sqlite.fossil
    
  2. Modify the WASM build flags in ext/wasm/GNUmakefile. Add -DSQLITE_ENABLE_FTS3 and -DSQLITE_ENABLE_FTS3_PARENTHESIS to the CFLAGS section:

    CFLAGS = \
      -DSQLITE_ENABLE_FTS5 \
      -DSQLITE_ENABLE_FTS3 \
      -DSQLITE_ENABLE_FTS3_PARENTHESIS \
      ...
    
  3. Compile the WASM binary:

    make -f ext/wasm/GNUmakefile
    
  4. Replace the default sqlite3.wasm in your project with the newly built file.

B. Validating the Custom Build

After rebuilding, execute PRAGMA compile_options; to confirm ENABLE_FTS3 is present. Test FTS3 functionality with a minimal virtual table creation.

Step 4: Use a Community-Maintained WASM Build with FTS3

If custom compilation is not feasible, seek community-maintained WASM builds that include FTS3. For example, the npm package @sqlite.org/[email protected] reportedly includes FTS3. However, this approach has drawbacks:

  • Security risks: Unofficial builds may include unvetted code.
  • Version locking: Sticking to older builds forfeits bug fixes and performance improvements in newer SQLite versions.

To test a community build:

npm install @sqlite.org/[email protected]

Then verify FTS3 availability as described in Step 1.

Step 5: Update Documentation and Code Comments

To prevent future confusion, annotate code and documentation with platform-specific notes. For example:

-- Requires SQLite C build or custom WASM with FTS3 enabled
CREATE VIRTUAL TABLE legacy_data USING fts3(content);

Step 6: Report Documentation Gaps to the SQLite Team

While the SQLite documentation is generally comprehensive, the WASM build’s module differences are not prominently highlighted. Submit a documentation issue via the SQLite forum or GitHub repository, requesting clarifications such as:

"FTS3 and FTS4 are excluded from official SQLite WASM builds. Use FTS5 or compile a custom build with -DSQLITE_ENABLE_FTS3."

Final Recommendation

Migrate to FTS5 unless tightly coupled to FTS3-specific features. FTS5 offers better performance, richer query syntax, and long-term support. Reserve custom builds with FTS3 for legacy systems where migration is prohibitively expensive. Always validate module availability when switching SQLite versions or build sources.

Related Guides

Leave a Reply

Your email address will not be published. Required fields are marked *