PHPackages                             helmich/typo3-typoscript-lint - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. helmich/typo3-typoscript-lint

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

helmich/typo3-typoscript-lint
=============================

Static code analysis for the TypoScript configuration language.

v3.3.0(1y ago)902.9M↑31.2%20[12 issues](https://github.com/martin-helmich/typo3-typoscript-lint/issues)[3 PRs](https://github.com/martin-helmich/typo3-typoscript-lint/pulls)20MITPHPPHP ^8.1CI passing

Since Oct 30Pushed 9mo ago8 watchersCompare

[ Source](https://github.com/martin-helmich/typo3-typoscript-lint)[ Packagist](https://packagist.org/packages/helmich/typo3-typoscript-lint)[ Docs](https://github.com/martin-helmich)[ Fund](https://donate.helmich.me)[ GitHub Sponsors](https://github.com/martin-helmich)[ RSS](/packages/helmich-typo3-typoscript-lint/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (12)Versions (45)Used By (20)

TypoScript Lint: CGL validation for TypoScript
==============================================

[](#typoscript-lint-cgl-validation-for-typoscript)

[![Build status](https://github.com/martin-helmich/typo3-typoscript-lint/actions/workflows/php.yml/badge.svg?branch=master)](https://github.com/martin-helmich/typo3-typoscript-lint/actions/workflows/php.yml/badge.svg?branch=master)

Author
------

[](#author)

Martin Helmich (typo3 at martin-helmich dot de)

Contents
--------

[](#contents)

- [Synopsis](#synopsis)
- [Why?!](#why)
- [Getting started](#getting-started)
    - [Setup](#setup)
    - [Usage](#usage)
    - [Example](#example)
- [Code validation](#code-validation)
    - [Features](#features)
    - [Configuration](#configuration)
- [Articles](#articles)
- [Future features](#future-features)

Synopsis
--------

[](#synopsis)

This package contains a tool that can parse TYPO3's configuration language, "TypoScript", into an syntax tree and perform static code analysis on the parsed code. `typoscript-lint` can generate [Checkstyle](http://checkstyle.sourceforge.net/)-compatible output and can be used in Continuous Integration environments.

Why?!
-----

[](#why)

This project started of as a private programming excercise. I was writing an article for the [T3N](http://t3n.de) magazine on Continuous Integration for TYPO3 projects, introducing tools like [JSHint](http://www.jshint.com/) or [CSSLint](http://csslint.net/), and I noticed that no comparable tools exist for TypoScript. So I thought, "What the heck, let's go" and at some point realized that my little programming excercise might actually be useful to someone. So, that's that. Enjoy.

Getting started
---------------

[](#getting-started)

### Setup (using Composer)

[](#setup-using-composer)

Install typo3-typoscript-lint with Composer:

```
composer require --dev helmich/typo3-typoscript-lint

```

Of course, this works best if your TYPO3 project is also Composer-based. If it isn't, you can also install the Linter [globally using the `composer global`](https://getcomposer.org/doc/03-cli.md#global) command:

```
composer global require helmich/typo3-typoscript-lint

```

### Setup (using [Phive](https://phar.io/))

[](#setup-using-phive)

Alternatively, you can also install typo3-typoscript-lint with Phive:

```
phive install martin-helmich/typo3-typoscript-lint

```

In this case, it will be installed into the `./tools` folder of your current directory:

```
./tools/typoscript-lint path/to/your.typoscript

```

### Usage

[](#usage)

Call typo3-typoscript-lint as follows:

```
vendor/bin/typoscript-lint path/to/your.typoscript

```

By default, it will print a report on the console. To generate a checkstyle-format XML file, call as follows:

```
vendor/bin/typoscript-lint -f xml -o checkstyle.xml path/to/your.typoscript

```

To generate a report formatted according to the GNU Coding Standards, call as follows:

```
vendor/bin/typoscript-lint -f gcc path/to/your.typoscript

```

### Example

[](#example)

[![asciicast](https://camo.githubusercontent.com/b300ba7f0ff09c4b9e1b2965ae38e3e493c4afb660515d05e1484286f46d045e/68747470733a2f2f61736369696e656d612e6f72672f612f316a4f4a76335a366f6e575364496b54417841577347676f792e706e67)](https://asciinema.org/a/1jOJv3Z6onWSdIkTAxAWsGgoy)

Code validation
---------------

[](#code-validation)

### Features

[](#features)

Certain aspects of code validation are organized into so-called "sniffs" (I borrowed the term from PHP's CodeSniffer project). Currently, there are sniffs for checking the following common mistakes or code-smells in TypoScript:

#### Indentation

[](#indentation)

The indentation level should be increased with each nested statement. In the configuration file, you can define whether you prefer [tabs or spaces](http://www.jwz.org/doc/tabs-vs-spaces.html) for indentation.

```
foo {
    bar = 2
  baz = 5
# ^----------- This will raise a warning!
}

```

By default, the indentation sniff expects code inside TypoScript conditions to be **not** indented. You can change this behaviour by setting the `indentConditions` flag for the indentation sniff to `true` in your `typoscript-lint.yml`configuration file (see below).

#### Dead code

[](#dead-code)

Code that was commented out just clutters your source code and obstructs readability. Remove it, that's what you have version control for (you **do**use version control, do you?).

```
foo {
    bar.baz = 5
    #baz.foo = Hello World
#   ^----------- This will raise a warning!
}

```

#### Whitespaces

[](#whitespaces)

Check that no superflous whitespace float around your operators.

```
#   v----------- This will raise a warning (one space too much)
foo  {
    bar= 3
#      ^-------- This will also raise a warning (one space too few)
}

```

#### Repeating values

[](#repeating-values)

If the same value is assigned to different objects, it might be useful to extract this into a TypoScript constant.

```
foo {
    bar = Hello World
    baz = Hello World
#         ^----- Time to extract "Hello World" into a constant!

```

By default, any value with a length of 8 characters or more will trigger a warning if it is repeated more than once. You can configure this threshold by setting the `valueLengthThreshold` parameter for the `RepeatingRValueSniff` in your configuration file.

It is also possible to whitelist certain values that are allowed to repeat. You can set those in the `allowedRightValues` parameter in your configuration file.

#### Duplicate assignments

[](#duplicate-assignments)

Assigning a value to the same object multiple times. Works across nested statements, too.

```
foo {
    bar = baz
#   ^----------- This statement is useless, because foo.bar is unconditionally overwritten!
}
foo.bar = test

```

The sniff is however smart enough to detect conditional overwrites. So the following code will *not* raise a warning:

```
foo {
    bar = baz
}

[globalString = ENV:foo = bar]
foo.bar = test
[global]

```

#### Nesting consistency

[](#nesting-consistency)

This sniff checks if nesting assignments are used in a consistent manner. Consider the following example:

```
foo {
    bar = test1
}

foo {
    baz = test2
}

```

In this case, the two nested statements might very well be merged into one statement.

Consider another example:

```
foo {
    bar = test1
}

foo.baz {
    bar = test2
}

```

In this case, both statements could be nested in each other.

#### Empty blocks

[](#empty-blocks)

Raises warnings about empty assignment blocks:

```
foo {
}

```

#### Discourage config.no\_cache = 1

[](#discourage-configno_cache--1)

Raises warning about usage of `config.no_cache = 1`. Instead USER\_INT or COA\_INT should be used.

### Configuration

[](#configuration)

`typoscript-lint` looks for a file `typoscript-lint.yml` in the current working directory. If such a file is found, it will be merged with the `typoscript-lint.dist.yml` from the installation root directory. Have a look at [said file](typoscript-lint.dist.yml) for an idea of what you can configure (granted, not much yet):

**Note**: Previous versions of this tool used the filename `tslint.yml` for their configuration files. This conflicted with the [same-named tool for linting TypeScript](https://palantir.github.io/tslint/), and is thus considered deprecated (although the old file names are still supported).

- The paths to lint can be set under the `paths` key:

    ```
    paths:
      - directory/with/typoscript
      - ...
    ```

    You can also use the `*` character to match multiple files or directories:

    ```
    paths:
      - typo3conf/ext/yourprefix_*/Configuration/TypoScript
    ```
- Configure individual sniffs under the `sniff` key in the configuration file. This key consists of a list of objects, each with a `class` key and an optional `parameters`key.

    Since a local configuration file will be merged with the distributed configuration file, you *cannot* disable sniffs by simply removing them from the local configuration file (see this [bug report](https://github.com/martin-helmich/typo3-typoscript-lint/issues/1)for more information). To disable a sniff, use the `disabled` configuration property. For example, to disable the `DeadCode` sniff:

    ```
    sniffs:
      - class: DeadCode
        disabled: true
    ```
- Configure file extensions that should be treated as TypoScript files in the `filePatterns` key. This key may contain a list of glob patterns that inspected files need to match. This is especially relevant when you're running `typoscript-lint`on entire directory trees:

    ```
    filePatterns:
      - "*.typoscript"
      - "setup.txt"
      - # ...
    ```

    If you have certain files you want to explicitly *exclude* from linting even if they match the `filePatterns` above, you can specify additional `excludePatterns`:

    ```
    filePatterns:
      - "*.typoscript"
    excludePatterns:
      - "Constants.typoscript"
    ```

    You can also exclude whole directories from linting:

    ```
    excludePatterns:
      - "*/vendor/*"
    ```

Articles
--------

[](#articles)

- [Code Quality in TYPO3 Projects](https://www.martin-helmich.de/en/blog/codequality-typo3.html)
- [Continuous Integration in TYPO3 Projects (*German*)](https://t3n.de/magazin/continuous-integration-typo3-236672/)
- [Integrate TYPO3 Linting with Gitlab CI](https://daniel-siepmann.de/Posts/2018/2018-01-30-gitlab-ci-linting.html) *by Daniel Siepmann*
- [Integrate Typoscript linter into VIM](https://daniel-siepmann.de/Posts/2018/2018-01-28-typoscript-linter-inside-vim.html) *by Daniel Siepmann*

Future features
---------------

[](#future-features)

- Sniffs for more code smells (ideas are welcome)
- Full test coverage (no, I did not do TDD. Shame on me.)
- Automated fixing of found errors

###  Health Score

61

—

FairBetter than 99% of packages

Maintenance48

Moderate activity, may be stable

Popularity57

Moderate usage in the ecosystem

Community43

Growing community involvement

Maturity84

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 85.3% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~96 days

Recently: every ~85 days

Total

36

Last Release

474d ago

Major Versions

v1.2.3 → v2.x-dev2017-01-05

v1.5.0 → v2.0.02019-03-23

v2.5.2 → v3.0.02022-10-16

PHP version history (7 changes)v1.0.0PHP &gt;=5.4

v2.x-devPHP &gt;=5.6

v1.4.0PHP &gt;=5.5

v2.0.0PHP ^7.2

v2.5.0PHP ^7.2|^8.0

v3.0.0PHP ^7.4 || ^8.0

v3.2.0PHP ^8.1

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/38724147?v=4)[helmich](/maintainers/helmich)[@helmich](https://github.com/helmich)

---

Top Contributors

[![martin-helmich](https://avatars.githubusercontent.com/u/2538958?v=4)](https://github.com/martin-helmich "martin-helmich (314 commits)")[![oliverklee](https://avatars.githubusercontent.com/u/765746?v=4)](https://github.com/oliverklee "oliverklee (30 commits)")[![maikschneider](https://avatars.githubusercontent.com/u/696865?v=4)](https://github.com/maikschneider "maikschneider (4 commits)")[![mbrodala](https://avatars.githubusercontent.com/u/5037116?v=4)](https://github.com/mbrodala "mbrodala (4 commits)")[![chrissonntag](https://avatars.githubusercontent.com/u/39337016?v=4)](https://github.com/chrissonntag "chrissonntag (3 commits)")[![cseifert](https://avatars.githubusercontent.com/u/78357?v=4)](https://github.com/cseifert "cseifert (3 commits)")[![DanielSiepmann](https://avatars.githubusercontent.com/u/354250?v=4)](https://github.com/DanielSiepmann "DanielSiepmann (2 commits)")[![dependabot-preview[bot]](https://avatars.githubusercontent.com/in/2141?v=4)](https://github.com/dependabot-preview[bot] "dependabot-preview[bot] (2 commits)")[![tmotyl](https://avatars.githubusercontent.com/u/515397?v=4)](https://github.com/tmotyl "tmotyl (2 commits)")[![kevin-appelt](https://avatars.githubusercontent.com/u/25666167?v=4)](https://github.com/kevin-appelt "kevin-appelt (1 commits)")[![stefanszymanski](https://avatars.githubusercontent.com/u/2189734?v=4)](https://github.com/stefanszymanski "stefanszymanski (1 commits)")[![dependabot-support](https://avatars.githubusercontent.com/u/112581971?v=4)](https://github.com/dependabot-support "dependabot-support (1 commits)")[![tillhoerner](https://avatars.githubusercontent.com/u/31031406?v=4)](https://github.com/tillhoerner "tillhoerner (1 commits)")

---

Tags

continuous-integrationlinterlintingphptypo3typoscripttyposcript-lint

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/helmich-typo3-typoscript-lint/health.svg)

```
[![Health](https://phpackages.com/badges/helmich-typo3-typoscript-lint/health.svg)](https://phpackages.com/packages/helmich-typo3-typoscript-lint)
```

###  Alternatives

[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.4k5.6M651](/packages/sylius-sylius)[shopware/platform

The Shopware e-commerce core

3.3k1.5M3](/packages/shopware-platform)[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.3M152](/packages/sulu-sulu)[simplesamlphp/simplesamlphp

A PHP implementation of a SAML 2.0 service provider and identity provider.

1.1k12.4M193](/packages/simplesamlphp-simplesamlphp)[prestashop/prestashop

PrestaShop is an Open Source e-commerce platform, committed to providing the best shopping cart experience for both merchants and customers.

9.0k15.4k](/packages/prestashop-prestashop)[symplify/monorepo-builder

Not only Composer tools to build a Monorepo.

5205.3M82](/packages/symplify-monorepo-builder)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
