Quick start
-
Install the runner. One package, one binary.
Terminal window pnpm add -D @arguslab/argusFor type-checking, point TypeScript at the shipped declarations — it does not find them on its own. See Installation → TypeScript.
tsconfig.json { "compilerOptions": { "types": ["@arguslab/argus"] } } -
Write something to test. Argus bundles your test and its imports, so the module under test has to exist — an unresolved import is a bundle failure, not a red test.
src/money.ts export function formatCents(cents: number): string {if (cents < 0) throw new RangeError('amount must not be negative');return (Math.round(cents) / 100).toFixed(2);} -
Write a test. No import of the test API is needed —
describe,test,it,expectand the hooks are installed as globals inside the Hermes realm.src/money.test.ts import { formatCents } from './money';describe('formatCents', () => {test('formats whole euros', () => {expect(formatCents(1200)).toBe('12.00');});test('rounds half up', () => {expect(formatCents(1205)).toBe('12.05');});test('rejects a negative amount', () => {expect(() => formatCents(-1)).toThrow(RangeError);});}); -
Run it.
Terminal window pnpm exec argus "src/**/*.test.ts"✓ hermes v1 hermes-v250829098.0.16 · prebuilt darwin-arm64 · ~/.argus/cache/…/bin/hermesformatCents✓ formats whole euros✓ rounds half up✓ rejects a negative amount3 passed, 0 failed, 0 todo, 3 total (0 ms in Hermes)✓ money.test.ts1 files: 1 passed, 0 failed3 tests: 3 passed, 0 failed, 0 todoThat first line is the prebuilt path, which applies on React Native 0.86 and 0.87. On other versions Argus names a different source — see How the binary is provisioned.
-
Break it on purpose, so you can see what a failure looks like.
test('rounds half up', () => {expect(formatCents(1205)).toBe('12.06'); // wrong});formatCents✓ formats whole euros✗ rounds half up — expect("12.05").toBe("12.06")Error: expect("12.05").toBe("12.06")at toBe (…/argus-MCNniB/run.argus-bundle.js:1105:24)at apply (native)at counted (…/argus-MCNniB/run.argus-bundle.js:437:26)at anonymous (src/money.test.ts:9:31)…✓ rejects a negative amount2 passed, 1 failed, 0 todo, 3 total (0 ms in Hermes)✗ money.test.ts (1 of 3 failed)1 files: 0 passed, 1 failed3 tests: 2 passed, 1 failed, 0 todoOne frame in that stack is yours —
src/money.test.ts:9:31, the line you just broke, notrun.argus-bundle.js:1105. Frames inside the bundle stay as bundle frames on purpose: they are Argus’ own, and pretending they map to your source would be a lie. See Source maps. -
Add it to
package.jsonso it runs like any other check.package.json {"scripts": {"test:hermes": "argus \"src/**/*.test.ts\" \"src/**/*.test.tsx\""}}Or move the globs into an optional
argus.config.tsand leave the script as plainargus— see Configuration.
What just happened
Section titled “What just happened”For that one file, Argus:
- Read
node_modules/react-nativeto find which Hermes engine and version your project pins. - Resolved a binary for it — cache, then the published prebuilt, verifying its checksum.
- Bundled the test and its imports into a single sealed IIFE, lowered to the Hermes syntax envelope, with an external source map.
- Spawned
hermeson that file, in its own process. - Read back exactly one framed result line carrying a private per-run nonce.
- Remapped every stack frame to your source, and rendered the report.
Where to go next
Section titled “Where to go next”- Test structure — hooks,
.skip/.only/.todo, nesting. - Matchers — the full
expectsurface. - Mocks & spies —
argus.fn(),argus.spyOn(), call matchers. - Component testing —
render,screen,fireEvent. - Command and flags — timeouts, concurrency, engine selection.
- Configuration —
argus.config.ts, and which source wins.