hem testhem test emits the project’s siblings, then runs Vitest with the Hem plugin wired in and the emitted TSX transform pinned to a JSX runtime. Use it for suites without a Vite or Vitest config. If a standard config exists in the current directory, the command stops before emitting or testing and directs you to your project’s Vitest command.
Vitest and @hem-lang/vite-plugin resolve from your project, not from the CLI, so your installed versions are the ones that run. If either is missing the command says so and exits.
Write the test
Tests are ordinary TypeScript. Import the .hem module and the specifier resolves to its emitted sibling:
import { expect, test } from "vitest";
import { nextOccurrence } from "./schedule.hem";
test("advances to the next month", () => {
expect(nextOccurrence(new Date("2026-01-31"), 1)).toEqual(new Date("2026-02-28"));
});You can also import the emitted .tsx directly when you want to assert on the generated output itself.
Narrow what runs
hem test schedulePositional arguments pass through to Vitest as test file path filters. Use -- before a path filter beginning with -. Other Vitest options such as -t and --coverage are rejected; run your project’s Vitest command for those modes. hem test --help lists the supported options.
Re-run on change
hem test --watchLeaves Vitest running. Editing a .hem file re-emits its sibling and re-runs the affected tests.
Point the JSX transform somewhere else
The emitted TSX transform defaults to react. For another runtime:
hem test --jsx-import-source preactTest Effect code against a different transport
hem test --effect effectThis overrides hem.effectImportSource for the test run only, which is what you want when checking whether a newer Effect release satisfies the capability probe. Leave it off and the tsconfig value applies, so tests and builds agree by default.
Use the project’s Vitest config
Register @hem-lang/vite-plugin alongside the existing plugins in your Vite or Vitest config and run vitest directly. Preserve the project’s setup files, environment, coverage, and test selection. The application owns JSX configuration when using the plugin directly; see Vite integration.
import { defineConfig } from "vitest/config";
import { hem } from "@hem-lang/vite-plugin";
export default defineConfig({
plugins: [hem()],
test: { setupFiles: ["./test/setup.ts"] },
});vitest runhem test refuses standard vitest.config.* and vite.config.* files in the current directory, including JavaScript and TypeScript module variants. It does not load custom config paths; use your project’s command for those too.
For the full option list, see the CLI reference.