eslint-plugin-o1js
raw JSON → 0.4.0 verified Fri May 01 auth: no javascript
ESLint plugin with rules for o1js (formerly SnarkyJS) Smart Contract development. Version 0.4.0 is stable, released via npm. It detects invalid patterns such as throws, if/ternary statements, use of JSON/random functions in circuits, state variable limit (max 8), and constructor overriding. Designed for TypeScript projects using o1js to build zero-knowledge smart contracts on Mina Protocol. Alternative to manual code review for o1js circuit constraints.
Common errors
error Failed to load plugin 'o1js': Cannot find module 'eslint-plugin-o1js' ↓
cause Plugin not installed or missing from node_modules.
fix
Run 'npm install eslint-plugin-o1js --save-dev' or the equivalent for your package manager.
error Parsing error: The keyword 'const' is reserved ↓
cause ESLint is not configured to parse TypeScript.
fix
Install '@typescript-eslint/parser' and set 'parser: '@typescript-eslint/parser'' in your ESLint config.
error Definition for rule 'o1js/no-throw-in-circuit' was not found ↓
cause Rule name is incorrect or plugin not loaded properly.
fix
Ensure plugin is listed in 'plugins: ["o1js"]' and rule name matches one of the available rules (e.g., 'o1js/no-throw-in-circuit').
Warnings
gotcha Plugin only works with TypeScript projects using @typescript-eslint/parser. Plain JavaScript is not supported. ↓
fix Ensure your ESLint config uses parser: '@typescript-eslint/parser' and enable TypeScript parsing.
breaking Plugin enforces that SmartContract constructor cannot be overridden. This may break existing code that defines custom constructors. ↓
fix Move constructor logic to a @method or use a deployment pattern that does not override the constructor.
deprecated In future versions, rules may be renamed or removed. The 'recommended' config is the stable path forward. ↓
fix Use 'plugin:o1js/recommended' and avoid referencing individual rules by name unless necessary.
gotcha State variable limit rule checks only the number of @state decorated properties. Non-decorated properties are not counted but may still cause issues. ↓
fix Manually verify that total internal state objects do not exceed 8, including those without @state decorator.
gotcha ESLint plugin does not detect dynamic method calls (e.g., this['someMethod']()) in circuits; only static analysis is performed. ↓
fix Avoid using computed property names or dynamic method calls in circuit methods.
Install
npm install eslint-plugin-o1js yarn add eslint-plugin-o1js pnpm add eslint-plugin-o1js Imports
- plugin wrong
const plugin = require('eslint-plugin-o1js')correctimport plugin from 'eslint-plugin-o1js' - rules
import { rules } from 'eslint-plugin-o1js' - configs
import { configs } from 'eslint-plugin-o1js'
Quickstart
// .eslintrc.cjs
module.exports = {
parser: '@typescript-eslint/parser',
plugins: ['o1js'],
extends: ['plugin:o1js/recommended'],
};
// Example smart contract that violates rules
import { SmartContract, state, State, method } from 'o1js';
export class MyContract extends SmartContract {
@state({ type: Field }) privateField = State<Field>();
@state({ type: Field }) privateField2 = State<Field>();
@state({ type: Field }) privateField3 = State<Field>();
@state({ type: Field }) privateField4 = State<Field>();
@state({ type: Field }) privateField5 = State<Field>();
@state({ type: Field }) privateField6 = State<Field>();
@state({ type: Field }) privateField7 = State<Field>();
@state({ type: Field }) privateField8 = State<Field>();
@state({ type: Field }) privateField9 = State<Field>(); // error: too many state variables
@method init() {
super.init();
if (this.someCondition) { // error: if statement in circuit
throw new Error('fail'); // error: throw in circuit
}
}
}