npm package: @re2tools/re2-wasm
Description: Lightweight WebAssembly wrapper around Google RE2. ESM-only, works in Node, browser, React, Angular, Storybook.
Latest version: 1.0.2

# @re2tools/re2-wasm

Lightweight WebAssembly wrapper around [Google RE2](https://github.com/google/re2). ESM-only; works in **Node.js 18+**, **browser**, **React 16+**, **Angular 14+**, and **Storybook 7+**.

- **No top-level await** — call `RE2.initialize()` once, then use sync API
- **Singleton WASM** — HMR-safe, no double instantiation
- **Small target** — WASM &lt; 600KB (vs re2js ~3.34MB)
- **No catastrophic backtracking** — RE2 guarantees linear time

## Installation

```bash
npm install @re2tools/re2-wasm
```

## Quick start

### Node.js (18+)

```js
import RE2 from '@re2tools/re2-wasm';

await RE2.initialize();

const re = new RE2('\\d+');
console.log(re.test('hello42'));  // true
console.log(re.exec('hello42'));  // [ '42', index: 5, input: 'hello42' ]
console.log(re.replace('a1b2', 'X'));  // 'aXbX' (with g flag)
```

### Browser

```html
<script type="module">
  import RE2 from 'https://cdn.example.com/@re2tools/re2-wasm/dist/index.js';

  await RE2.initialize('/wasm/re2.wasm');

  const re = new RE2('world');
  console.log(re.test('hello world'));  // true
</script>
```

See [docs/node.md](docs/node.md), [docs/browser.md](docs/browser.md), [docs/react.md](docs/react.md), [docs/angular.md](docs/angular.md), [docs/storybook.md](docs/storybook.md) for framework-specific setup.

## API (sync after `initialize()`)

| Method | Description |
|--------|-------------|
| `RE2.initialize(urlOrPath?)` | **Async.** Load WASM once. Call before any other use. |
| `new RE2(pattern, flags?)` | Constructor. `pattern` can be string or `RegExp`. |
| `RE2.compile(pattern, flags?)` | Same as `new RE2(...)`. |
| `re.test(input)` | Returns `true` if pattern matches. |
| `re.exec(input)` | Returns match array or `null` (like `RegExp.prototype.exec`). |
| `re.match(input)` | Like `String.prototype.match`. |
| `re.replace(input, replacement)` | Like `String.prototype.replace`. |
| `re.split(input, limit?)` | Like `String.prototype.split`. |

**Properties:** `source`, `flags`, `global`, `ignoreCase`, `multiline`, `dotAll`, `unicode`, `lastIndex`.

## WASM hosting

- **Node:** WASM is resolved from the package `wasm/` directory next to the built JS.
- **Browser / Vite / Webpack:** Copy or serve `node_modules/@re2tools/re2-wasm/wasm/re2.wasm` and pass its URL to `RE2.initialize(url)` if the default resolution fails.

See [docs/browser.md](docs/browser.md) for Vite/Webpack and CDN notes.

## Common errors and fixes

| Error | Fix |
|-------|-----|
| "RE2 not initialized" | Call `await RE2.initialize()` before using any RE2 API. |
| "Failed to load WASM" | Ensure `re2.wasm` is present in `wasm/` and (in browser) served with correct MIME or path. |
| Node ESM path error | Use `"type": "module"` and import from the package name; avoid `__dirname` in user code. |

See [docs/troubleshooting.md](docs/troubleshooting.md) for more.

## Performance

- Target WASM size &lt; 600KB.
- No catastrophic backtracking (unlike JS `RegExp` on certain patterns).
- Stable under heavy loops; no async in hot paths after `initialize()`.

## Differences from JS RegExp

- **RE2 syntax** — Some PCRE/JS features (e.g. lookbehind, backreferences) are not supported; see [RE2 syntax](https://github.com/google/re2/wiki/Syntax).
- **One async step** — Only `RE2.initialize()` is async; all instance methods are synchronous after that.
- **Singleton** — One WASM instance per process/page; safe with HMR.

## Build (WASM from source)

Prerequisites: Emscripten SDK, Google RE2 (include + lib).

```bash
# Set RE2 paths if needed
export RE2_INC=/usr/local/include RE2_LIB=/usr/local/lib
npm run build:wasm
```

This produces `wasm/re2.wasm`. The script runs the following (see `scripts/build-wasm.sh`):

```bash
emcc -Os -flto -fno-exceptions -fno-rtti \
  -s WASM=1 -s ENVIRONMENT=web,node -s FILESYSTEM=0 \
  -s ALLOW_MEMORY_GROWTH=1 -s ASSERTIONS=0 -s SAFE_HEAP=0 \
  -s STACK_OVERFLOW_CHECK=0 -s MINIMAL_RUNTIME=1 \
  -s EXPORTED_FUNCTIONS='["_re2_test","_re2_exec","_malloc","_free"]' \
  -s EXPORTED_RUNTIME_METHODS='[]' \
  -I "$RE2_INC" cpp/re2_wrapper.cc -L "$RE2_LIB" -lre2 -o build/re2.js
```

Emscripten outputs `re2.js` and `re2.wasm`; the package uses only `re2.wasm` with `WebAssembly.instantiate`. Target WASM size is under 600KB.

## License

Apache-2.0