npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

k6-gherkin

v0.0.31

Published

Unopinionated Gherkin BDD test runner and summary reporter for k6

Readme

k6-gherkin

Unopinionated Gherkin BDD test runner and summary reporter for Grafana k6.

k6-gherkin allows you to write living business specifications using standard Gherkin (.feature files) and execute them natively inside k6 using your own custom JavaScript or TypeScript step definitions.


Why does this exist?

TL;DR: One spec, two jobs—prove it works, then prove it holds up under load, plain enough for the team, precise enough to check an LLM's work against.

Selenium, Cypress, Playwright, and others are good at what they're built for: driving a real browser through a user flow and asserting on what happens. Performance testing isn't that job—there's no clean way to parameterize virtual users or ramping stages, and their reporting is built around one run's pass/fail rather than latency and throughput over time. Macro-recording tools like JMeter take the opposite angle and cover the load side, and module controllers or parameterization can make a recording reusable—but the test plan itself stays opaque outside the team that wrote it. A product owner or domain expert can't open it and tell what user behavior it's actually exercising.

Realistic load isn't one endpoint hit as hard as possible—it's the paths real users take through the app, at scale, described in a shared language engineers and the people who define "correct" behavior can both read and agree on. A Gherkin scenario captures that path as behavior, kept separate from both how it's automated (the step definitions) and how much load sits behind it (virtual users, ramp-up strategy). Write "user adds an item to their cart" once, reuse the same steps across scenarios, and change the load profile without touching the behavior being tested.

k6 was built for performance testing first, with scriptable load profiles and reporting that actually answers "how does this behave under load?" A functional check is just a load test with one virtual user, so it's a solid foundation for functional checks too. What it lacked was Gherkin—no native way to run .feature files—and that's the piece this fills: write scenarios in plain Gherkin, back them with step definitions in JS/TS, and run the same spec as a functional check or a full load test, with k6's native reporting either way. The goal is for this to be a one-stop shop for testing—functional and performance, in the same suite, described in language plain enough for the whole team to read, not just the engineers who automate it. That same plainness is what makes .feature files useful for reviewing AI-written code: narrow and executable enough to read as the spec, run it, and see whether an LLM's implementation actually does what it claims—rather than having to read the implementation to find out.

That ambition doesn't reach UI testing yet. k6 Studio can record a flow the way JMeter does and generate a script from it—a fine seed for a Gherkin scenario—but neither it nor k6's own browser module (Chromium over CDP) has caught up to the cross-browser coverage or debugging tooling Cypress and Playwright already offer. Real gap, not a hidden one.


Key Features

  • True BDD Separation: Write technology-agnostic .feature files in pure business language.
  • Custom Step Definitions: Register custom step matching functions using Given, When, Then, And, But.
  • Protocol & Backend Agnostic: Test gRPC, REST/HTTP, WebSockets, or GraphQL services.
  • Native k6 Reporting: Integrated handleSummary reporter formats test checks into a BDD hierarchy (Feature → Scenario → ✓ Step).
  • Zero Go Compilation: Pure JavaScript/TypeScript adapter—runs with standard k6 without needing xk6 or custom binaries.

Installation

npm install k6-gherkin

Usage Example

1. Define your Feature (features/shopping-cart.feature)

Feature: Shopping Cart
  Scenario: Add item to cart
    Given an authenticated user
    When the user adds "Wireless Headphones" to their shopping cart
    Then the shopping cart should contain 1 item

2. Write Step Definitions (steps/cart-steps.ts)

import type { Given, When, Then, StepContext } from 'k6-gherkin';

// A step file exports one factory function; k6-gherkin calls it with a Given/When/Then/And/But
// shared across all step files in stepsDir. Nothing is imported from 'k6-gherkin' at runtime —
// only `import type`, which is erased before k6 ever tries to resolve it — so step files have
// zero runtime dependency on this package, matching k6's own module loader (relative/absolute
// file paths and remote URLs only, no node_modules resolution).
export default function (Given: Given, When: When, Then: Then) {
  Given(/^an authenticated user$/, async (ctx: StepContext) => {
    ctx.userToken = 'auth-token-123';
  });

  When(/^the user adds "([^"]+)" to their shopping cart$/, async (ctx: StepContext, item: string) => {
    // Execute HTTP or gRPC request using k6
    ctx.cartItems = [item];
  });

  Then(/^the shopping cart should contain 1 item$/, async (ctx: StepContext) => {
    ctx.check(ctx.cartItems, {
      'cart has item': (items) => items && items.length === 1,
    });
  });
}

3. Run with k6-gherkin

const { runK6 } = require('k6-gherkin');

runK6({
  featuresDir: './features',
  stepsDir: './steps',
});

Summary Output

When executed, k6 check results are formatted directly in the console output:

Feature: Shopping Cart

  Scenario: Add item to cart
    ✓ Given an authenticated user
    ✓ When the user adds "Wireless Headphones" to their shopping cart
    ✓ Then the shopping cart should contain 1 item

────────────────────────────────────────────────────────────
✓ 3 checks: 3 passed
✓ threshold: checks rate == 1

License

MIT