Skip to content

Tracking issue for the deprecation and removal of wasm2js (AKA WASM=0) #27608

Description

@sbc100

This would also include the removal of -sWASM=2 (which builds both JS and wasm versions of a program in a single command)>

The process for deprecating and removing features from emscripten is laid out
in https://github.com/emscripten-core/emscripten/blob/main/CONTRIBUTING.md#deprecating-settings-and-features.

At any point in the process we may decide to delay or abort the deprecation and close this issue.

Deprecation checklist:

  • Open an issue (this)
  • Add "deprecation" warning to emcc
  • Send message to emscripten-discuss
  • Perform global search for usage in public repos
  • Wait at least 4 releases or 2 months
  • Remove feature from codebase

Activity

  1. changed the title [-]Tracking issue for the deprecation and removal of wasm2js (-sWASM=0)[/-] [+]Tracking issue for the deprecation and removal of wasm2js (`WASM=0`)[/+] on Aug 25, 2026
  2. changed the title [-]Tracking issue for the deprecation and removal of wasm2js (`WASM=0`)[/-] [+]Tracking issue for the deprecation and removal of wasm2js (AKA `WASM=0`)[/+] on Aug 25, 2026
  3. sbc100 commented on Oct 6, 2026

    @sbc100
    CollaboratorAuthor

    I confirmed that google internally no more users of emscripten's wasm2js feature.

  4. sbc100 commented on Oct 6, 2026

    @sbc100
    CollaboratorAuthor

    AI generated report on current usage on the public internet:

    Ran global searches across GitHub Code Search (including .github/workflows
    and commit history since 2025), Sourcegraph (excluding forks and archived
    repos), and Debian Code Search for -sWASM=0, -s WASM=0, -sWASM=2,
    -s WASM=2, and -sNO_WASM.

    High-Level Summary

    • Raw GitHub counts:
      • "-sWASM=0": ~1,596 files | "-s WASM=0": ~5,528 files
      • "-sWASM=2": ~92 files | "-s WASM=2": ~86 files
      • "-sNO_WASM" / "-s NO_WASM": 8 files (none active outside emscripten
        tests)
    • Most hits are inactive/noise: The vast majority of matches are old
      generated Emscripten JS files ("Build with -s WASM=0 to target JavaScript instead"), commented-out template flags (e.g., raylib's # -sWASM=0),
      unmaintained repos from the 2017–2020 era (often paired with removed flags
      like --memory-init-file 0 or --llvm-lto 1), or vendored copies of a few
      upstream libraries (libwebp, draco, libsodium, xxHash, sql.js).
    • Note that WebAssembly/binaryen already dropped its -sWASM=0 build in
      Feb 2026 (#7995), and Rust removed the asmjs-unknown-emscripten target.

    1. Active Users of -sWASM=2 / -s WASM=2

    Usage of WASM=2 is nearly non-existent in active projects; 0 repositories
    on GitHub use -sWASM=2 or -s WASM=2 in .github/workflows. The only active
    repositories referencing it are:

    1. openframeworks/apothecary (apothecary/apothecary,
      modified Oct 2026):
      • Passes export LINK_FLAGS="-s WASM=2 -pthread -matomics -mbulk-memory ..."
        in its Emscripten dependency build script.
    2. OpenMPT/openmpt (build/make/config-emscripten.mk,
      modified June 2026):
      • Supports EMSCRIPTEN_TARGET=all which sets LDFLAGS += -s WASM=2 -s LEGACY_VM_SUPPORT=1 (as well as EMSCRIPTEN_TARGET=js which sets
        -s WASM=0), though wasm (-s WASM=1) is also supported.
    3. krkrsdl2/krkrsdl2 (CMakeLists.txt, modified Sept 2025):
      • Has an off-by-default CMake option KRKRSDL2_EMSCRIPTEN_ENABLE_JS_FALLBACK
        that appends -sWASM=2.
    4. qbs/qbs (tests/auto/blackbox/tst_blackbox.cpp, modified Sept
      2026; also in Debian Code Search):
      • Qt's Qbs build tool has blackbox tests verifying expected output file
        suffixes (.js, .wasm, .wasm.js) when passing -sWASM=0, -sWASM=1,
        and -sWASM=2.

    2. Active Users of -sWASM=0 / -s WASM=0

    A. Actively Building or Testing -sWASM=0 in CI / Default Releases

    1. sql-js/sql.js (13.7k stars, Makefile & CI.yml, using
      Emscripten 5.0.0):
      • Actively builds, tests (npm run test-asm, test-asm-debug,
        test-asm-memory-growth), and publishes sql-asm.js and
        worker.sql-asm.js release artifacts with -s WASM=0 alongside its Wasm
        builds.
    2. jedisct1/libsodium (14k stars,
      dist-build/emscripten.sh, modified Sept 2026):
      • Always builds an asm.js fallback (emccLibsodium ... -Oz -s WASM=0) and
        concatenates it as a backup module inside libsodium.js alongside the Wasm
        build.
    3. Cyan4973/xxHash (11.3k stars, .github/workflows/ci.yml,
      modified Sept 2026; also in Debian Code Search):
      • Has an active GitHub Actions CI step Scalar asm.js (-sWASM=0) running
        LDFLAGS="-sWASM=0" make clean check under Node (currently pinned to
        emsdk 3.1.33 in CI).
    4. Yahweasel/libav.js (530 stars, Makefile, modified Aug
      2026):
      • Builds and ships .asm.js and .asm.mjs variants (-s WASM=0) alongside
        .wasm.js and .wasm.mjs variants for FFmpeg audio/video codecs.
    5. justjake/quickjs-emscripten (1.7k stars,
      scripts/prepareVariants.ts, modified Feb 2026):
      • Publishes @jitl/quickjs-asmjs-mjs-release-sync using -s WASM=0 -s SINGLE_FILE=1 for constrained JS environments without WebAssembly, though
        it currently pins ASMJS_EMSCRIPTEN_VERSION = "3.1.43" (while using
        5.0.1 for Wasm variants).
    6. alpertron/calculators (254 stars, w.bat / Makefile,
      modified Sept 2026):
      • Builds an asm.js fallback version with -s WASM=0 alongside its Wasm
        builds.

    B. Recent Projects Targeting Wasm-less JS Environments (2025–2026)

    1. Haskell / MicroHs / Mobile JS runtimes (dmjio/miso,
      haskell-miso/miso-lynx)
      :
      • dmjio/miso (2.4k stars, modified Oct 2026 in PR #1663): Uses
        emcc -sWASM=0 for its browser_js MicroHs target (nix/mhs/default.nix,
        Makefile.mhs) and in sample-app/app.cabal / miso-lynx (targeting
        ByteDance's Lynx mobile engine).
    2. React Native / Bundler single-file JS (poe-platform/poe-code,
      KittenML/KittenTTS-react-native)
      :
      • poe-platform/poe-code (packages/media-codecs/scripts/build.mjs,
        modified Oct 2026): Uses Emscripten 4.0.13 with -sWASM=0 -sWASM_ASYNC_COMPILATION=0 to bundle media codecs as pure JS.
      • KittenML/KittenTTS-react-native
        (scripts/build-cephonemizer.js, modified May 2026): Uses -sWASM=0 so
        React Native's Metro bundler can bundle the runtime as plain JS without
        native/asset glue.
    3. PDF-embedded C/C++ apps (ading2210/linuxpdf, EvanZhouDev/llm.pdf,
      nikol4ss/doom-pdf)
      :
      • Compile TinyEMU, llama.cpp, and Doom with emcc -sWASM=0 so they can
        execute inside Chrome PDFium / Adobe Acrobat's embedded JS runtime, which
        does not expose WebAssembly.

    C. Major Upstream Libraries with Optional / Legacy -sWASM=0 Targets

    These active projects still have -sWASM=0 in their build scripts behind
    non-default options (and are the source of most vendored hits in other repos
    and Debian Code Search):

    • opencv/opencv (platforms/js/build_js.py): Passes
      -s WASM=0 only when --disable_wasm is explicitly passed on the CLI.
    • google/draco (cmake/draco_emscripten.cmake): Appends
      -sWASM=0 when the CMake option DRACO_WASM is OFF.
    • webmproject/libwebp (CMakeLists.txt): Defines a webp_js
      SDL demo target with -sWASM=0 (alongside webp_wasm with -sWASM=1) when
      WEBP_BUILD_WEBP_JS is enabled and WEBP_ENABLE_SIMD is off.
    • rive-app/rive-runtime (build/setup_compiler.lua): Passes
      -sWASM=0 when configured with --emsdk=js instead of --emsdk=wasm.
    • ton-blockchain/ton (emulator/CMakeLists.txt): Appends
      -sWASM=0 only if USE_EMSCRIPTEN_NO_WASM is set.
    • MiniZinc/libminizinc
      (cmake/support/config_emscripten.cmake): Defines a minizinc_asm CMake
      target with -s WASM=0 alongside minizinc_wasm.
    • sciapp/gr (CMakeLists.txt): Sets -sWASM=0 in its EMSCRIPTEN
      CMake block (also appears in Debian's gr-framework package).

    D. Build Tools & Toolchains

    • emscripten-core/emsdk:
      • bazel/emscripten_toolchain/toolchain.bzl still defines a
        crosstool_cpu_asmjs feature that passes flags = ["-sWASM=0"].
      • test/test.py runs do_build(' -s WASM=0', is_expected=False).
    • conan-io/conan (conan/tools/build/flags.py): Returns
      "-sWASM=0" when arch == "asm.js" and compiler == "emscripten".
    • bkaradzic/bx (scripts/toolchain.lua, vendored into mame,
      crown, etc.): Defines an asmjs target config with "-s WASM=0".
  5. sbc100 commented on Oct 6, 2026

    @sbc100
    CollaboratorAuthor
  6. cohunter commented on Oct 9, 2026

    @cohunter

    Hello, apologies for the late comment, I’ve just seen this issue.

    Use case not covered in the survey: Apple Lockdown Mode (iOS/iPadOS/macOS)

    Lockdown Mode is Apple’s hardening setting for journalists, activists and others at risk of targeted spyware. In WebKit it disables the JIT and WebAssembly entirely: typeof WebAssembly === 'undefined' in Safari with Lockdown on (verified on iOS 26). The only way to run C/C++/Rust code for those users is plain JavaScript, i.e. wasm2js.

    I’m building Lockdown-compatible media playback for a web subtitle editor. HEVC (hevc.js), VP9 (libvpx), AV1 (dav1d) and E-AC-3 (Rust, via binaryen’s wasm2js) all run as plain JS in Lockdown Mode at usable speed in the interpreter. For video codecs there’s no other route: Lockdown also disables WebCodecs video.

    I understand the maintenance cost, and I’m not asking to keep -sWASM=0 itself. A supported migration path would be enough. Either of these would do:

    1. Keep binaryen’s standalone wasm2js maintained, and document how to run an Emscripten -sWASM=1 build’s output through it (e.g. a small WebAssembly shim that instantiates the wasm2js module).
    2. Keep the wasm2js runtime piece of the JS glue as an opt-in library, even if emcc no longer drives it.

    Our users have no WebAssembly by design, so they’re the audience this removal hits hardest.

  7. sbc100 commented on Oct 9, 2026

    @sbc100
    CollaboratorAuthor

    Oh no... that is indeed an annoying/worrying use case. I wonder if there are any plans to add a WebAssembly interpreter in that mode? I think this is what MS edge did for their locked down mode.

    We do plan on keeping binaryen’s standalone wasm2js around yes. There are other users of that tool.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions