Solidity code linter providing security and style guide validations for smart contract development
—
Multiple formatter functions for different output formats and integration needs. Solhint provides various formatters to present linting results in different formats suitable for human reading, CI/CD integration, and tool consumption.
Default human-readable formatter with colors and clear structure (default formatter).
/**
* Default human-readable formatter with colors and clear structure
* @param {Array<Reporter>} reports - Array of Reporter instances
* @returns {string} Formatted output string with colors and styling
*/
function stylish(reports);Usage Examples:
const stylish = require('solhint/lib/formatters/stylish');
const reports = [/* Reporter instances */];
const output = stylish(reports);
console.log(output);
// CLI usage
// solhint contracts/*.sol (uses stylish by default)
// solhint -f stylish contracts/*.solOutput Format:
contracts/Token.sol
10:5 error Explicitly mark visibility in function func-visibility
15:8 warning Line length exceeds 120 characters max-line-length
✖ 2 problems (1 error, 1 warning)Machine-readable JSON output for programmatic consumption and CI/CD integration.
/**
* Machine-readable JSON output for programmatic consumption
* @param {Array<Reporter>} reports - Array of Reporter instances
* @returns {string} JSON string containing structured results
*/
function json(reports);Usage Examples:
const json = require('solhint/lib/formatters/json');
const output = json(reports);
const results = JSON.parse(output);
// Process results programmatically
results.forEach(file => {
console.log(`File: ${file.filePath}`);
console.log(`Errors: ${file.errorCount}`);
file.messages.forEach(msg => {
console.log(` ${msg.line}:${msg.column} ${msg.message}`);
});
});
// CLI usage
// solhint -f json contracts/*.sol > results.jsonOutput Format:
[
{
"filePath": "contracts/Token.sol",
"messages": [
{
"line": 10,
"column": 5,
"severity": 2,
"message": "Explicitly mark visibility in function",
"ruleId": "func-visibility"
}
],
"errorCount": 1,
"warningCount": 0
}
]Tabular output format for clear columnar presentation of results.
/**
* Tabular output format for clear columnar presentation
* @param {Array<Reporter>} reports - Array of Reporter instances
* @returns {string} Table-formatted output string
*/
function table(reports);Usage Examples:
const table = require('solhint/lib/formatters/table');
const output = table(reports);
console.log(output);
// CLI usage
// solhint -f table contracts/*.solOutput Format:
┌─────────────────────┬──────┬────────┬──────────┬─────────────────────────────────────┬───────────────────┐
│ File │ Line │ Column │ Severity │ Message │ Rule ID │
├─────────────────────┼──────┼────────┼──────────┼─────────────────────────────────────┼───────────────────┤
│ contracts/Token.sol │ 10 │ 5 │ error │ Explicitly mark visibility │ func-visibility │
│ contracts/Token.sol │ 15 │ 8 │ warning │ Line length exceeds 120 characters │ max-line-length │
└─────────────────────┴──────┴────────┴──────────┴─────────────────────────────────────┴───────────────────┘Compact single-line format for each issue, suitable for grep and simple parsing.
/**
* Compact single-line format for each issue
* @param {Array<Reporter>} reports - Array of Reporter instances
* @returns {string} Compact formatted output string
*/
function compact(reports);Usage Examples:
const compact = require('solhint/lib/formatters/compact');
const output = compact(reports);
console.log(output);
// CLI usage
// solhint -f compact contracts/*.solOutput Format:
contracts/Token.sol: line 10, col 5, Error - Explicitly mark visibility in function (func-visibility)
contracts/Token.sol: line 15, col 8, Warning - Line length exceeds 120 characters (max-line-length)Unix-style format compatible with editors and IDEs that parse compiler output.
/**
* Unix-style format compatible with editors and IDEs
* @param {Array<Reporter>} reports - Array of Reporter instances
* @returns {string} Unix-formatted output string
*/
function unix(reports);Usage Examples:
const unix = require('solhint/lib/formatters/unix');
const output = unix(reports);
console.log(output);
// CLI usage
// solhint -f unix contracts/*.solOutput Format:
contracts/Token.sol:10:5: Explicitly mark visibility in function [func-visibility]
contracts/Token.sol:15:8: Line length exceeds 120 characters [max-line-length]Test Anything Protocol (TAP) format for integration with TAP-consuming test runners.
/**
* Test Anything Protocol (TAP) format for test runners
* @param {Array<Reporter>} reports - Array of Reporter instances
* @returns {string} TAP-formatted output string
*/
function tap(reports);Usage Examples:
const tap = require('solhint/lib/formatters/tap');
const output = tap(reports);
console.log(output);
// CLI usage
// solhint -f tap contracts/*.solOutput Format:
TAP version 13
1..2
not ok 1 - contracts/Token.sol:10:5: Explicitly mark visibility in function (func-visibility)
not ok 2 - contracts/Token.sol:15:8: Line length exceeds 120 characters (max-line-length)Static Analysis Results Interchange Format (SARIF) for security tooling and CI/CD integration.
/**
* Static Analysis Results Interchange Format (SARIF) for security tooling
* @param {Array<Reporter>} reports - Array of Reporter instances
* @returns {string} SARIF JSON formatted output string
*/
function sarif(reports);Usage Examples:
const sarif = require('solhint/lib/formatters/sarif');
const output = sarif(reports);
const sarifData = JSON.parse(output);
// Process SARIF data
console.log('Tool:', sarifData.runs[0].tool.driver.name);
console.log('Results:', sarifData.runs[0].results.length);
// CLI usage
// solhint -f sarif contracts/*.sol > results.sarifOutput Format:
{
"version": "2.1.0",
"$schema": "https://json.schemastore.org/sarif-2.1.0.json",
"runs": [
{
"tool": {
"driver": {
"name": "solhint",
"version": "6.0.1",
"rules": [
{
"id": "func-visibility",
"shortDescription": {
"text": "Explicitly mark visibility in function"
}
}
]
}
},
"results": [
{
"ruleId": "func-visibility",
"level": "error",
"message": {
"text": "Explicitly mark visibility in function"
},
"locations": [
{
"physicalLocation": {
"artifactLocation": {
"uri": "contracts/Token.sol"
},
"region": {
"startLine": 10,
"startColumn": 5
}
}
}
]
}
]
}
]
}const { processPath } = require('solhint');
const stylish = require('solhint/lib/formatters/stylish');
const json = require('solhint/lib/formatters/json');
// Process files
const reports = processPath('contracts/**/*.sol');
// Format for human reading
const humanOutput = stylish(reports);
console.log(humanOutput);
// Format for tools
const jsonOutput = json(reports);
fs.writeFileSync('lint-results.json', jsonOutput);# Default formatter (stylish)
solhint contracts/*.sol
# Specific formatter
solhint -f json contracts/*.sol
# Save formatted output
solhint -f sarif contracts/*.sol > security-report.sarif
solhint -f json contracts/*.sol > lint-results.json# GitHub Actions example
- name: Run Solhint
run: |
solhint -f json 'contracts/**/*.sol' > lint-results.json
- name: Process Results
run: |
node -e "
const results = JSON.parse(require('fs').readFileSync('lint-results.json'));
const errors = results.reduce((sum, file) => sum + file.errorCount, 0);
if (errors > 0) process.exit(1);
"// Create custom formatter wrapper
function customFormatter(reports) {
const jsonResults = json(reports);
const data = JSON.parse(jsonResults);
// Custom processing
return data.map(file => ({
file: file.filePath,
issues: file.messages.length,
critical: file.messages.filter(m => m.severity === 2).length
}));
}
const reports = processPath('contracts/**/*.sol');
const customOutput = customFormatter(reports);
console.log(JSON.stringify(customOutput, null, 2));| Formatter | Use Case | Machine Readable | Colors | Structure |
|---|---|---|---|---|
| stylish | Development, terminal output | No | Yes | Human-friendly |
| json | CI/CD, programmatic processing | Yes | No | Structured data |
| table | Reports, documentation | No | No | Tabular |
| compact | Grep, simple parsing | Partial | No | One-line |
| unix | Editor integration | Partial | No | Standard format |
| tap | Test runners | Yes | No | TAP protocol |
| sarif | Security tools, compliance | Yes | No | Industry standard |
Formatters handle various edge cases:
// Example error handling
function safeFormat(formatter, reports) {
try {
return formatter(reports || []);
} catch (error) {
console.error('Formatter error:', error.message);
return 'Error formatting results';
}
}Install with Tessl CLI
npx tessl i tessl/npm-solhint