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
IDE Integration
Install the platformOS Check extension for VS Code to get inline diagnostics, hover documentation, and code actions directly in your editor. The extension uses the same Language Server bundled with pos-cli.
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.