# 04 - BACKWARD COMPATIBILITY ## 4.1 Node.js Compatibility 3va prioritizes compatibility with the Node.js ecosystem. ## 4.2 Compatible APIs Measured, not estimated. The table is generated by `scripts/compat-table.sh` from a run of nodejs/node's own `test/parallel` suite with 3va (`scripts/setup-node-tests.sh` plus the `node_tests` runner; see `docs/09-testing/07-compatibilidad-node.md` §7.4 step 2). Compatibility = passed / (passed + failed); tests skipped because they need a Node/V8 flag or reach into Node internals are counted separately and excluded. Measured on 3va 2.13.0 against nodejs/node v24.22.0 (commit `f14cd3aa`), 2026-10-22, for the 17 modules whose baseline is committed (`test/parallel` prefixes `buffer`, `child-process`, `crypto`, `events`, `fs`, `http`, `https`, `net`, `os`, `path`, `querystring`, `stream`, `string-decoder`, `timers`, `url`, `util`, `zlib`). This is the pass rate of Node's own tests for a module, not a per-function claim. | Module | Passed | Failed | Skipped | Compatibility | |---|---:|---:|---:|---:| | `buffer` | 11 | 51 | 7 | 17.7% | | `child-process` | 9 | 94 | 10 | 8.7% | | `crypto` | 17 | 122 | 18 | 12.2% | | `events` | 0 | 5 | 3 | 0.0% | | `fs` | 60 | 179 | 36 | 25.1% | | `http` | 120 | 271 | 12 | 30.7% | | `https` | 8 | 57 | 2 | 12.3% | | `net` | 31 | 116 | 11 | 21.1% | | `os` | 1 | 4 | 2 | 20.0% | | `path` | 5 | 11 | 0 | 31.2% | | `querystring` | 0 | 3 | 0 | 0.0% | | `stream` | 21 | 147 | 47 | 12.5% | | `string-decoder` | 0 | 2 | 0 | 0.0% | | `timers` | 23 | 23 | 12 | 50.0% | | `url` | 0 | 14 | 1 | 0.0% | | `util` | 3 | 15 | 13 | 16.7% | | `zlib` | 6 | 59 | 0 | 9.2% | | **total** | **315** | **1173** | **174** | **21.2%** | An earlier version of this section carried hand-written "self-reported" percentages (e.g. `buffer` 100%, `crypto` 97%, `http` 99%). They were never measured against Node's suite and, as the first measurement shows, were far too optimistic; they have been removed. Where a module has no measured figure yet, this document says so instead of guessing. The specific factual sub-claims the old notes made (which named `crypto.subtle`/`util.parseArgs`/`path.matchesGlob` functions exist or not) are now covered by the `crypto`/`util`/`path` rows' failed tests, which the baseline lists one by one. ## 4.3 Compatibility Flags — NOT IMPLEMENTED **None of the flags below exist in `crates/cli/src/main.rs`.** This section was written as an aspirational placeholder and never built or removed — `3va run --compat` / `--preset=node` are not real flags today. Left here as a possible future feature, not a claim about current behavior. | Flag | Description | |------|-------------| | --compat | Maximum compatibility mode | | --preset=node | Simulate Node.js | ## 4.4 Automatic Polyfills 3va automatically polyfills unavailable APIs: ```javascript // Automatic fetch AbortController TextEncoder Performance // Requires flag crypto (some algorithms) ``` ## 4.5 Breaking Changes **Same caveat as §4.3** — `--legacy-security` does not exist as a flag; this table predates any real 1.0/0.9 release and doesn't correspond to an actual migration path. For the real, current breaking-change history see `docs/CHANGELOG.md` and `3va codemod --from=1 --to=2` (which is a real, implemented command — see `crates/cli/src/main.rs::run_codemod`). | Version | Change | Migration | |---------|--------|-----------| | 1.0 | Removed legacy API | Use new namespace | | 0.9 | Changed default security | --legacy-security | ## 4.6 Expo / React Native Compatibility 3va runs Expo packages in a web/server context without a bundler or device. ### Supported packages | Package | Version | Status | Notes | |---------|---------|--------|-------| | `expo-modules-core` | 56.0.14 | ✅ | Polyfill + real npm package loadable | | `expo-constants` | 56.0.16 | ✅ | Web variant via `ExponentConstants.web.js` | | `expo-asset` | 56.0.15 | ✅ | `@react-native/assets-registry` polyfilled | | `expo-font` | 56.0.5 | ✅ | Server path (`isServer = true`); `fontfaceobserver` available | | `expo-file-system` | 56.0.7 | ✅ | Web stubs via `ExpoFileSystem.web.ts` | | `react-native` | 0.79.0 | ✅ | Pre-cached polyfill (Platform, NativeModules, …) | ### How it works 1. **Platform extension priority** — `.web.ts/.web.js` files are resolved before `.ts/.js` so Expo packages load their server-safe implementations automatically. 2. **`process.env.EXPO_OS = 'web'`** — Expo packages branch on this to skip `registerWebModule()` calls that require a DOM. 3. **NativeModules** — only explicitly registered modules are exposed; unknown names return `undefined` (prevents truthy-proxy issues with conditional `JSON.parse` calls). 4. **ESM→CJS converter** — handles all TypeScript/ESM patterns used by Expo (enums, destructuring exports, `export {}` markers, circular re-exports). ### Known limitations - Native device APIs (camera, location, etc.) return stubs or throw `UnavailabilityError`. - `requireOptionalNativeModule` always returns `null` — intended for server environments. - `registerWebModule` returns the factory result directly (no DOM/web worker context). ## 4.7 Compatibility Testing `3va test --compat` and `3va test-compat ` below are **not real subcommands** — `3va test` has no `--compat` flag and there is no `test-compat` command in `crates/cli/src/main.rs`. The last two lines are real and are how Expo/framework compatibility is actually verified today: ```bash # NOT IMPLEMENTED — aspirational, do not run 3va test --compat 3va test-compat express 3va test-compat lodash # Expo / ESM→CJS integration tests (real, implemented) cargo test -p vvva_js --test pipeline cargo test -p vvva_js --test framework_compat ``` --- *Compatibility targeting 99% Node.js API parity + Expo web/server package support.*