platformOS Check - Development Tool
platformOS Check
platformOS Check is a Node.js-based linter and language server for platformOS Liquid templates. It is part of the platformos-tools monorepo and is bundled with pos-cli.
Installation
Install pos-cli globally via npm — platformOS Check and the Language Server are included:
npm install -g @platformos/pos-cli
You can also install the linter as a standalone package for use in build pipelines:
npm install --save-dev @platformos/platformos-check-node
CLI Usage
Run the linter on your project:
pos-cli check run [path]
Available options:
| Flag | Description |
|---|---|
-a |
Enable automatic fixing of offenses |
-f <format> |
Output format: text (default) or json |
-s, --silent |
Only show errors, no success messages |
Initialize a .platformos-check.yml configuration file with all available settings:
pos-cli check init
Download the latest platformOS Liquid documentation used by the linter:
pos-cli check update-docs
Start the Language Server Protocol (LSP) server for IDE integration:
pos-cli lsp
Configuration
You can configure platformOS Check to override default check options, enable or disable specific checks. You can make these changes using a config file, disable checks using comments, or selectively run checks using command line flags.
Config file
Add a .platformos-check.yml file to the root of your project to override check defaults. The easiest way to create one is by running pos-cli check init, which generates a config file with all available settings commented out for reference.
The config file supports the following top-level settings:
| Setting | Description |
|---|---|
| extends | Base configuration to extend. Available presets: platformos-check:recommended (default), platformos-check:all, platformos-check:nothing. You can also extend another YAML config file or an npm package. |
| root | If your app/modules aren't in the root directory, you can provide a relative root path for finding the platformOS app files. |
| ignore | Exclude directories from platformOS Check. Useful if you use private modules and do not have access to the files. |
| require | Paths to custom check modules (JS files or npm packages). See Writing custom checks. |
| check settings | For each check, set enabled to true or false, set the check severity, set specific ignore files and paths, and configure any other check-specific options. |
Example config file
# Extend the recommended preset (this is the default if omitted)
extends:
- platformos-check:recommended
# Ignore directories
ignore:
- node_modules/**
- modules/third-party-private-module/**
# Paths to custom check modules
require:
- ./my-custom-checks/index.js
# Disable a check
MissingPartial:
enabled: false
# Change severity and configure options for a check
UnusedAssign:
enabled: true
severity: error
# Configure a check with custom options
MissingPartial:
enabled: true
severity: warning
ignore:
- modules/legacy/**
ignore_missing:
- shared/deprecated-*
Check severity
The check severity indicates the relative importance of a check. Severity levels are:
| Severity | Description |
|---|---|
error |
Critical issues that indicate bugs or broken functionality |
warning |
Issues that should be addressed but don't break functionality |
info |
Style and best practice suggestions |
For backwards compatibility, suggestion (maps to warning) and style (maps to info) are also accepted in configuration files.
When running pos-cli check run, the process exits with code 1 if any offenses are found.
Disable checks using Liquid comments
You can disable all checks or specific checks using comments. You can disable checks for a specific section of your app code, or for an entire file.
Disable all checks for a section of your file:
{% # platformos-check-disable %}
{% assign x = 1 %}
{% # platformos-check-enable %}
Disable a specific check by including it in the comment:
{% # platformos-check-disable UnusedAssign %}
{% assign x = 1 %}
{% # platformos-check-enable UnusedAssign %}
Disable multiple checks by including them as a comma-separated list:
{% # platformos-check-disable UnusedAssign,UndefinedObject %}
{% assign x = 1 %}
{% # platformos-check-enable UnusedAssign,UndefinedObject %}
Disable checks for the entire document by placing the comment on the first line:
{% # platformos-check-disable MissingPartial %}
{% render 'legacy-partial' %}
Available checks
The following checks are available in the platformos-check:recommended preset:
| Check | Default Severity | Description |
|---|---|---|
| DeprecatedFilter | warning | Reports usage of deprecated Liquid filters |
| DeprecatedTag | warning | Reports usage of deprecated Liquid tags |
| DuplicateFunctionArguments | warning | Reports duplicate arguments in function calls |
| DuplicateRenderPartialArguments | warning | Reports duplicate arguments in render tags |
| GraphQLCheck | error | Validates GraphQL syntax |
| GraphQLVariablesCheck | error | Validates GraphQL variables |
| ImgWidthAndHeight | error | Requires width and height on img tags |
| InvalidHashAssignTarget | error | Reports invalid hash assign targets |
| JSONSyntaxError | error | Reports JSON syntax errors |
| LiquidHTMLSyntaxError | error | Reports Liquid/HTML syntax errors |
| MatchingTranslations | error | Validates translation keys match across locales |
| MetadataParamsCheck | error | Validates metadata parameters |
| MissingAsset | error | Reports references to missing assets |
| MissingPartial | error | Reports references to missing partials |
| OrphanedPartial | warning | Reports partials that are not referenced anywhere |
| ParserBlockingScript | error | Reports scripts that block HTML parsing |
| TranslationKeyExists | error | Reports usage of non-existent translation keys |
| UnclosedHTMLElement | warning | Reports unclosed HTML elements |
| UndefinedObject | warning | Reports usage of undefined variables |
| UniqueDocParamNames | error | Reports duplicate @param names in LiquidDoc |
| UnknownFilter | error | Reports usage of unknown Liquid filters |
| UnknownProperty | error | Reports usage of unknown properties |
| UnrecognizedRenderPartialArguments | warning | Reports unrecognized arguments in render tags |
| UnusedAssign | warning | Reports assigned but unused variables |
| UnusedDocParam | warning | Reports @param tags for unused parameters |
| ValidDocParamTypes | error | Validates @param type annotations |
| ValidHTMLTranslation | warning | Validates HTML in translations |
| ValidJSON | error | Validates JSON file contents |
| ValidRenderPartialArgumentTypes | warning | Validates argument types passed to partials |
| VariableName | warning | Enforces variable naming conventions (default: snake_case) |
Writing custom checks
You can extend platformOS Check with custom checks written in JavaScript. Custom checks are loaded via the require field in your .platformos-check.yml config file, or auto-discovered from npm packages named platformos-check-* or @your-org/platformos-check-* in your node_modules.
Custom check structure
A custom check module must export a checks array containing check definitions. Each check definition has a meta object describing the check and a create function that returns visitor methods.
Create a file, e.g. my-custom-checks/index.js:
const NoHardcodedStrings = {
meta: {
code: 'NoHardcodedStrings',
name: 'No hardcoded strings in HTML',
docs: {
description: 'Encourages use of translations instead of hardcoded strings.',
recommended: false,
},
// SourceCodeType: 'LiquidHtml' for Liquid files, 'JSON' for JSON, 'GraphQL' for GraphQL
type: 'LiquidHtml',
// Severity: 0 = error, 1 = warning, 2 = info
severity: 1,
schema: {},
targets: [],
},
create(context) {
return {
async TextNode(node) {
const text = node.value.trim();
if (text.length > 0 && /[a-zA-Z]{3,}/.test(text)) {
context.report({
message: `Consider using a translation key instead of hardcoded text: "${text.substring(0, 50)}"`,
startIndex: node.position.start,
endIndex: node.position.end,
});
}
},
};
},
};
module.exports = {
checks: [NoHardcodedStrings],
};
Then reference it in your .platformos-check.yml:
require:
- ./my-custom-checks/index.js
# Enable and configure your custom check
NoHardcodedStrings:
enabled: true
severity: warning
Visitor methods
The create function receives a context object and returns an object with visitor methods. The available visitor methods depend on the source code type:
For Liquid files (type: 'LiquidHtml'):
- Node type methods like
LiquidTag,LiquidVariable,HtmlElement,HtmlRawNode,TextNode,VariableLookup,AssignMarkup, etc. - Exit methods: append
:exitto any node type (e.g."LiquidTag:exit") onCodePathStart(file)— called before traversing a fileonCodePathEnd(file)— called after traversing a file
The context object provides:
context.report({ message, startIndex, endIndex, fix?, suggest? })— report an offensecontext.file— the current source code filecontext.settings— check-specific settings from the configcontext.toRelativePath(uri)/context.toUri(relativePath)— path utilitiescontext.fileExists(uri)— check if a file existscontext.getDefaultTranslations()— access translation data
Publishing custom checks as npm packages
If you name your npm package following the convention platformos-check-* or @your-org/platformos-check-*, it will be auto-discovered when installed in the project's node_modules — no require entry needed in the config.