allwright
← All posts
5 min readThe allwright team

Get started with allwright in TypeScript

Go from an empty folder to a passing, real-browser test in about five minutes, using @allwright.dev/vitest — no driver binaries, no manual browser setup.

typescriptvitestgetting-startedweb testing
@allwright.dev/vitestpage.goto · page.click · expectTSTypeScript clientallwrightcoreReal browserChromium · Firefox

allwright is a small core engine with an installable plugin per surface — web today, mobile, desktop, and API to come. The fastest way to feel that in your hands is the TypeScript client: install one package, write one test, and allwright drives a real Chromium or Firefox browser for you. No separate driver to download, no version to match by hand.

This walks through the exact steps behind allwright-typescript-sample, a minimal, working example repo. You can either follow along and build the project from scratch, or clone the sample and skip straight to running it.

git clone https://github.com/allwright-dev/allwright-typescript-sample
cd allwright-typescript-sample
npm install
npm test

If you'd rather understand each piece as you add it, keep reading — it's the same five files, built up one at a time. Just want the finished project without typing it out by hand? npm init allwright@latest scaffolds this exact setup in one command — see our post on the initializer.

Prerequisites

  • Node.js 18 or newer
  • npm (or your package manager of choice — the sample uses npm)
  • A real Chrome/Chromium or Firefox already installed on the machine — allwright drives whatever browser it finds locally, it doesn't download one for you

That's it for the browser plugin path. @allwright.dev/vitest can bootstrap the allwright engine and the web plugin itself on first run, or you can install both explicitly first — see the next section.

Install the engine and web plugin (optional)

@allwright.dev/vitest bootstraps the allwright engine and installs the web plugin for you automatically, so feel free to skip straight to the next section if you don't care what's happening underneath. If you'd rather have the CLI and plugin already in place before your first test — CI, an offline environment, or just wanting to watch the install happen once instead of on your first assertion — do it yourself:

curl -fsSL https://raw.githubusercontent.com/allwright-dev/allwright/main/scripts/install.sh | bash
allwright serve --listen-addr 127.0.0.1:50051 &
allwright plugin install web

allwright serve starts the gRPC engine that @allwright.dev/vitest talks to over 127.0.0.1:50051 by default; allwright plugin install web fetches the driverless Chromium/Firefox plugin from GitHub Releases ahead of time. Skip this, and the exact same two things happen automatically the moment your test needs them.

1. Start a new project

mkdir allwright-typescript-sample
cd allwright-typescript-sample
npm init -y

2. Install allwright's Vitest fixtures

@allwright.dev/vitest is a thin, Playwright-style layer over allwright's core TypeScript client: it hands your test a ready-to-use page fixture and a retrying expect for locator assertions, wired directly into Vitest.

npm install --save-dev typescript @allwright.dev/vitest

Your package.json should now look like this:

{
  "name": "allwright-typescript-sample",
  "version": "0.0.0",
  "private": true,
  "type": "module",
  "scripts": {
    "test": "vitest run",
    "test:watch": "vitest"
  },
  "devDependencies": {
    "typescript": "^5.6.3",
    "@allwright.dev/vitest": "^0.1.4"
  }
}

3. Configure TypeScript

Add a tsconfig.json that targets modern JS and points types at Vitest's globals, so test, expect, and friends are available without importing them in every file if you choose to use the globals style:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "types": ["vitest/globals"]
  },
  "include": ["src"]
}

4. Configure Vitest

A vitest.config.ts at the project root turns on globals and runs in the node environment — allwright drives a real, separate browser process, so your test file itself doesn't need a DOM environment like jsdom. Wrap your config in allwrightVitestConfig from @allwright.dev/vitest/config: it adds a Vitest global setup step that starts the allwright engine once for the whole run and shuts it down when your suite finishes, instead of every fixture bootstrapping its own:

import { defineConfig } from "vitest/config";
import { allwrightVitestConfig } from "@allwright.dev/vitest/config";
 
export default allwrightVitestConfig(
  defineConfig({
    test: {
      globals: true,
      environment: "node",
    },
  }),
);

5. Write your first test

Create src/themoderninternet.test.ts. This test opens a real site, clicks into a card by its visible text, and asserts that the destination heading becomes visible — the same locator-first style you'd expect from Playwright:

import { expect, test } from "@allwright.dev/vitest";
 
test("locator assertions", { timeout: 30000 }, async ({ page }) => {
  await page.goto("https://themoderninternet.vercel.app");
  await page.click("//*[@data-slot='card' and .//*[text()='Form Inputs']]//button")
  await expect(page.locator("//h1[text()='Form Inputs']")).toBeVisible()
});

A few things worth calling out:

  • { page } is injected for you. @allwright.dev/vitest launches and tears down the browser session around each test automatically — there's no browser.launch() / browser.close() boilerplate to write yourself.
  • Locators are plain XPath. You can reach into structure (.//*[text()=...]) the same way you'd query it by hand, without learning a new selector syntax.
  • expect(...).toBeVisible() retries. allwright's expect polls the locator until it matches or the timeout elapses, so you're not racing the page's own render.

6. Run it

npm test

For faster iteration while you're writing tests, run Vitest in watch mode instead:

npm run test:watch

If you skipped the optional install step above, the first run downloads and launches the allwright CLI, then lets the engine auto-install the web plugin the moment your test issues its first command — expect that one to take a little longer than the ones after it. Either way, allwright drives whatever Chrome/Chromium or Firefox is already installed on the machine; it doesn't download a browser for you.

Project structure, for reference

.
├── src/
│   └── themoderninternet.test.ts
├── package.json
├── tsconfig.json
└── vitest.config.ts

Five files, three of them config. That's deliberately the whole surface area — enough to be a real starting point, not a toy.

Where to go next

  • Point page.goto() at your own app and swap the locators for elements that actually exist there.
  • Skim Availability for the exact set of page actions and assertions that ship today, so you know what's real versus what's still on the roadmap.
  • Read How it works for the plugin model behind allwright, and how web fits alongside mobile, desktop, and API testing as those ship.
  • TypeScript isn't the only option — Rust, Go, Java, and Python clients are all published too, if your test suite lives somewhere else.

Try it in your own project

Scaffold a project with one command and run your first test, or keep reading the rest of the blog.