Open-source project
Behat/Gherkin avatar
Behat/Gherkin

Behat Gherkin: the PHP parser behind Cucumber-style feature files

Gherkin parser, written in PHP for Behat project

1,060 stars94 forksPHPMIT

At a glance

What is it?
Behat/Gherkin is the PHP library that turns a .feature file into a structured document object, with keyword tables for more than 40 languages shipped in i18n.php. It suits anyone building a Gherkin tool in PHP outside Behat itself, and it is unnecessary if you already run Behat, since the framework bundles it.
Who is it for?
Adopt Behat Gherkin when you need to read Gherkin feature files from PHP code of your own, for example a linter, a documentation generator or a custom runner, and when your users write features in a language other than English. Do not add it to a project that already depends on Behat, because you would be pulling in a second copy of a parser you already have.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 29 days ago.
What is it written in?
Mainly PHP, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A parser, not a test runner

Behat/Gherkin does one thing: it takes the text of a Gherkin feature file and returns a parsed representation of it. The README calls it the PHP Gherkin parser for Behat, and the description makes the scope plain. It is not a test framework, it does not execute step definitions, and it does not report results. Its audience is therefore two groups. The first is developers writing a tool in PHP that needs to understand Cucumber-style feature files, for example a linter, a documentation generator or an alternative runner. The second is anyone maintaining a Behat installation who needs to work with the parser layer directly. The first group is the one the library is genuinely for. If you already run Behat, the parser arrives with the framework, and depending on it separately means maintaining two copies of the same code in one project.

The whole API surface is visible in the README example.

php
$keywords = new Behat\Gherkin\Keywords\ArrayKeywords(array(
    'en' => array(
        'feature'          => 'Feature',
        'background'       => 'Background',
        'scenario'         => 'Scenario',
        'scenario_outline' => 'Scenario Outline|Scenario Template',
        'examples'         => 'Examples|Scenarios',
        'given'            => 'Given',
        'when'             => 'When',
        'then'             => 'Then',
        'and'              => 'And',
        'but'              => 'But'
    )
));
$lexer  = new Behat\Gherkin\Lexer($keywords);
$parser = new Behat\Gherkin\Parser($lexer);

$feature = $parser->parse(file_get_contents('some.feature'));

Three objects do the work: keywords, lexer, parser

The mechanism is a small pipeline of collaborators, and the README shows exactly how they connect. You build a keyword table first, handing it a locale code as the key and a set of keyword spellings as the value. A lexer takes that table, and a parser takes the lexer. Calling parse on the parser with the file contents returns the feature object, which is what most callers actually want. The design consequence is that the keyword table is the extension point. Language support is not compiled in as a switch statement, it is data you can replace, which is why an additional locale table is enough to make a second language work. The alternative to this arrangement, a parser that hardcodes English keywords, would need a code change to accept a feature file written in German or Japanese, and this one does not.

Language support is a data file, and a dialect like en-pirate proves it

The README states that the library comes bundled with support for more than 40 native languages, and points at i18n.php as the place where those definitions live. The usage example demonstrates the point with a locale called en-pirate, where the ordinary Gherkin keywords are replaced with pirate phrasing, given becomes Gangway! and but becomes Avast!. That example is a test fixture in disguise, and it makes the extension mechanism concrete: a dialect is a locale key and a mapping of ten keyword slots. The keyword slots are fixed by the language, covering feature, background, scenario, scenario_outline, examples, given, when, then, and but, and several accept alternatives separated by a pipe character, such as Scenario Outline|Scenario Template and Examples|Scenarios. The pipe form matters for real feature files, because it is how a single locale accepts two different spellings of the same construct.

Installing it means Composer, and the README's snippet is a starting point

The README's dependency section is short. It shows the standard Composer installer invocation and a php composer.phar update call, which is what you would run to pull the dependencies for the project itself rather than to install the library into an application. To use the library in your own PHP project, the usual route is a Composer requirement, and the package name follows the vendor and project name, so behat/gherkin is what you would put in a composer.json require block. The README shows the two shell commands it uses to prepare a working copy of the project itself.

shell
curl https://getcomposer.org/installer | php
php composer.phar update

The repository layout backs up the expectation of a normal library rather than an application: composer.json, src/, tests/, resources/, bin/, a phpunit.dist.xml for the test run, a phpstan.dist.neon for static analysis, .php-cs-fixer.dist.php for style, and a .roave-backward-compatibility-check.xml. That last file is worth noting on its own, because it means the project actively checks that public API does not break between releases.

The i18n keyword table is a compatibility contract of its own

Because the language definitions live in a PHP file rather than in compiled resources, a change to a keyword spelling would silently alter how existing feature files parse. An i18n.php at the repository root suggests the tables are code, reviewable in a diff, and that a mistake in them would be caught by the test suite. The README does not describe a policy for adding a new locale, and it does not say whether user-supplied keyword tables are merged with the bundled ones or replace them, so a project that wants both English and a custom dialect should confirm that behaviour against the code rather than assume it. The maintainer list gives a sense of the project's shape: Konstantin Kudryashov is credited as the original developer, and Andrew Coulton, Carlos Granados and Christophe Coevoet are named as current maintainers, with a separate document for notes on patches and pull requests.

Where a hand-written parser differs from this one

The realistic alternative to a dedicated Gherkin library is writing a parser yourself, which is what teams often do when their needs are narrow enough, such as a CI check that only needs scenario titles. The difference in approach is that a hand-written parser has to decide how to handle the parts of the grammar it does not care about, and the usual result is a regex that matches a subset and fails quietly on tags, doc strings, data tables or comments. This library already models the constructs, so the alternative saves code but pays in false negatives. The other alternative, using a Gherkin implementation in another language is not a drop-in option for PHP projects because it would mean a separate runtime or a service call. The trade is size against correctness, and for a project whose feature files are written by many people, correctness tends to win.

MIT licensed, and the pace of releases is visible in the tags

The project is MIT licensed, so it can be embedded in a commercial product without the licensing questions that a copyleft dependency would raise. The release history shows v4.18.0 tagged on 2026-09-25, v4.17.0 on 2026-05-18 and v4.16.1 on 2025-12-08, and the last push to the repository was on 2026-09-25. The gap between 4.16.1 and 4.17.0 is five months, and between 4.17.0 and 4.18.0 is four, so this is a project that ships on a slow, deliberate cadence rather than a weekly one. The maintainers describe Behat as free software maintained by volunteers and ask for contributions of time, and they point to sponsorship for the three named maintainers, which is an honest signal about the resource behind the release schedule. A CHANGELOG.md and CONTRIBUTING.md in the root, plus the pull request notes document, are the places to look for what changed and how patches are handled.

Editorial conclusion

Adopt Behat Gherkin when you need to read Gherkin feature files from PHP code of your own, for example a linter, a documentation generator or a custom runner, and when your users write features in a language other than English. Do not add it to a project that already depends on Behat, because you would be pulling in a second copy of a parser you already have. Verify first that the manual wiring shown in the README suits your codebase, since it builds the keywords object, lexer and parser by hand, and check i18n.php for the exact keyword spellings your feature files rely on before you assume the default English table matches your own.

Frequently asked questions

What does Behat Gherkin do?

It parses Gherkin feature files into PHP objects. The README shows building a keyword table, wrapping it in a Lexer, then passing that to a Parser, whose parse method returns the feature structure.

How many languages does Behat Gherkin support?

The README states the library ships with support for more than 40 native languages, and the keyword definitions live in the i18n.php file at the repository root.

Can I use custom keywords with the Behat Gherkin parser?

Yes. The keyword table is passed to the constructor as an array keyed by locale, and the README example defines a second locale called en-pirate with a different set of keyword spellings for the same slots.

Is Behat Gherkin licensed for commercial use?

The repository carries an MIT licence, which permits use in commercial applications. The README notes that the project is maintained by volunteers and asks for contributions or sponsorship to sustain it.

Official sources

  1. Behat/Gherkin on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/behat-gherkin.svg)](https://hysenlabs.com/projects/behat-gherkin)

Was this useful?