Explore the JavaScript SDK — From Template to Production-Ready Simulations

Why this guide exists

Build on the quick-start information from the Installation Guide and learn how to assemble production-ready scripts. This page collects the core building blocks—scenarios, feeders, checks, workload models, and operational tips—without forcing you through every editor action. If you need a slower pace, fall back to Create your first JavaScript-based simulation.

What you will cover

  • Anatomy of a maintainable simulation module.
  • Feeding data and correlating dynamic responses.
  • Choosing injection profiles that mimic real traffic.
  • Running, troubleshooting, and governing JavaScript-based load tests.

When we skip implementation details, we link to the relevant reference material so you can dive deeper on demand.

Prerequisites

  • Node.js 18 or newer (LTS releases recommended) with npm 8+.
  • A TypeScript-friendly editor (VS Code, WebStorm, etc.).
  • A non-production system you are allowed to exercise with load tests.
  • Optional: a Gatling Enterprise account for distributed execution.

Setup recap

Clone the se-ecommerce-demo-gatling-tests repository, install dependencies, and confirm that Gatling runs locally:

git clone https://github.com/gatling/se-ecommerce-demo-gatling-tests.git
cd se-ecommerce-demo-gatling-tests/javascript
npm install
npm run gatling:test -- --simulation src/basicSimulation.gatling

Need help with IDE configuration or project layout? Revisit the Installation Guide before continuing.

Understand the core concepts

Concept Description Deep dive
Simulation Default export of a .gatling.ts file that wires scenarios and injection. Simulation concepts
Protocol Shared configuration (e.g., base URL, headers) applied to one or more scenarios. HTTP protocol reference
Scenario Virtual user behavior—chains of requests, pauses, and logic. Scenario reference
Feeder Data source (arrays, CSV, custom functions) injected into sessions. Feeders reference
Checks & Assertions Response validations and pass/fail thresholds. Checks reference, Assertions
Injection Profile Defines arrival rate and ramp-up strategy. Injection reference

Mental model: translate your business journey into scenarios, feed them contextual data, drive them with an injection profile, and guard the outcome with assertions.

Assemble a baseline simulation

Start from a single module, then break logic into helpers as the script grows.

Baseline example

import { constantUsersPerSec, scenario, simulation } from "@gatling.io/core";
import { http, status } from "@gatling.io/http";

export default simulation((setUp) => {
  const httpProtocol = http
    .baseUrl("https://api-ecomm.gatling.io")
    .acceptHeader("application/json");

  const scn = scenario("JS Browse")
    .exec(
      http("GET session")
        .get("/session")
        .check(status().is(200))
    )
    .pause(1)
    .exec(
      http("GET catalog")
        .get("/catalog")
        .check(status().in(200, 304))
    );

  const usersPerSec = 2;
  const durationSeconds = 60;

  setUp(
    scn.injectOpen(constantUsersPerSec(usersPerSec).during(durationSeconds))
  ).protocols(httpProtocol);
});

Key points:

  • Keep protocol builders immutable and share them across scenarios with .protocols().
  • Use environment variables (or typed configuration helpers) for quick parameterisation.
  • Export the simulation as the module default so the Gatling CLI can pick it up automatically.

Enrich scenarios with data and behavior

Feeders: avoid hot-cache artifacts

import { exec, scenario } from "@gatling.io/core";
import { http, status } from "@gatling.io/http";
import products from "./resources/products.json" assert { type: "json" };

const productFeeder = () =>
  products[Math.floor(Math.random() * products.length)];

const browse = scenario("Browse with data").exec(
  (session) => session.set("product", productFeeder()),
  http("View product")
    .get((session) => `/items/${session.get<string>("product").sku}`)
    .check(status().is(200))
);
  • Store CSV/JSON under src/resources so they are bundled.
  • Pick a strategy (random, queue, circular) that balances uniqueness and repeatability. See the Feeders reference for additional helpers.

Correlation: capture dynamic values

import { scenario } from "@gatling.io/core";
import { css, http, status } from "@gatling.io/http";

const addWithCsrf = scenario("Add with CSRF")
  .exec(
    http("Get account")
      .get("/account")
      .check(css("input[name='csrfToken']", "value").saveAs("csrf"))
  )
  .pause(1)
  .exec(
    http("Submit form")
      .post("/account")
      .formParam("csrfToken", (session) => session.get<string>("csrf"))
      .check(status().in(200, 302))
  );
  • Pair extractors with a status/content check so failures surface immediately.
  • Choose the extractor that matches the response format (jsonPath, css, regex, etc.). The check reference lists every option.

Compose journeys

Break long user journeys into reusable chains:

import { exec, scenario } from "@gatling.io/core";
import { http, status } from "@gatling.io/http";

const search = exec(
  http("Search")
    .get("/search")
    .queryParam("q", (session) => session.get<string>("term"))
    .check(status().is(200))
);

const view = exec(
  http("View item")
    .get((session) => `/items/${session.get<string>("sku")}`)
    .check(status().in(200, 304))
);

const browse = scenario("Browse").repeat(3).on(search, view);

Extract common chains or helpers into separate modules (e.g., src/utils/protocols.ts) and import them where needed.

Model realistic workloads

Use injection profiles to express how traffic arrives. Combine warm-up, steady state, and cool-down phases to mimic production.

setUp(
  browse.injectOpen(
    nothingFor(5),
    rampUsers(50).during(30),
    constantUsersPerSec(10).during(60)
  ),
  addWithCsrf.injectOpen(constantUsersPerSec(2).during(90))
).assertions(
  global().successfulRequests().percent().gt(99),
  details("Browse", "Search").responseTime().percentile3().lt(1500)
);

// Import nothingFor, rampUsers, constantUsersPerSec, global, and details from "@gatling.io/core".

Need a refresher on each injection helper? Review the injection reference and the workload modelling guide.

Run and inspect results

  • Run locally with npm run gatling:test -- --simulation <path> or in interactive mode with --interactive.
  • After each run, open target/gatling/<simulation>-<timestamp>/index.html to review percentiles, throughput, and errors.
  • Automate the same commands in CI, or evaluate Gatling Enterprise for distributed load and real-time dashboards.

Operational hygiene

  • Commit simulations alongside application code and review them like any other change.
  • Externalize secrets via environment variables or Gatling Enterprise configuration-as-code.
  • Encode SLOs with assertions so builds fail fast when thresholds are breached.
  • Document scenario intent, metrics, and known caveats in README files or ADRs.

Where to go next

Edit this page on GitHub