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.
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 testIf 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 weballwright 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 -y2. 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/vitestYour 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/vitestlaunches and tears down the browser session around each test automatically — there's nobrowser.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'sexpectpolls the locator until it matches or the timeout elapses, so you're not racing the page's own render.
6. Run it
npm testFor faster iteration while you're writing tests, run Vitest in watch mode instead:
npm run test:watchIf 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.tsFive 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.