{"id":25521,"library":"eslint-plugin-o1js","title":"eslint-plugin-o1js","description":"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.","status":"active","version":"0.4.0","language":"javascript","source_language":"en","source_url":null,"tags":["javascript","eslint","snarkyjs","o1js","typescript"],"install":[{"cmd":"npm install eslint-plugin-o1js","lang":"bash","label":"npm"},{"cmd":"yarn add eslint-plugin-o1js","lang":"bash","label":"yarn"},{"cmd":"pnpm add eslint-plugin-o1js","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required to parse TypeScript smart contract code","package":"@typescript-eslint/parser","optional":false},{"reason":"Peer dependency for plugin functionality","package":"eslint","optional":false}],"imports":[{"note":"ESM-only; use dynamic import if using CommonJS.","wrong":"const plugin = require('eslint-plugin-o1js')","symbol":"plugin","correct":"import plugin from 'eslint-plugin-o1js'"},{"note":"Named export for accessing individual rule definitions.","wrong":null,"symbol":"rules","correct":"import { rules } from 'eslint-plugin-o1js'"},{"note":"Use configs.recommended in extends array.","wrong":null,"symbol":"configs","correct":"import { configs } from 'eslint-plugin-o1js'"}],"quickstart":{"code":"// .eslintrc.cjs\nmodule.exports = {\n  parser: '@typescript-eslint/parser',\n  plugins: ['o1js'],\n  extends: ['plugin:o1js/recommended'],\n};\n\n// Example smart contract that violates rules\nimport { SmartContract, state, State, method } from 'o1js';\n\nexport class MyContract extends SmartContract {\n  @state({ type: Field }) privateField = State<Field>();\n  @state({ type: Field }) privateField2 = State<Field>();\n  @state({ type: Field }) privateField3 = State<Field>();\n  @state({ type: Field }) privateField4 = State<Field>();\n  @state({ type: Field }) privateField5 = State<Field>();\n  @state({ type: Field }) privateField6 = State<Field>();\n  @state({ type: Field }) privateField7 = State<Field>();\n  @state({ type: Field }) privateField8 = State<Field>();\n  @state({ type: Field }) privateField9 = State<Field>(); // error: too many state variables\n\n  @method init() {\n    super.init();\n    if (this.someCondition) { // error: if statement in circuit\n      throw new Error('fail'); // error: throw in circuit\n    }\n  }\n}","lang":"typescript","description":"Shows how to configure ESLint with o1js plugin and demonstrates rule violations for excessive state variables, if statements, and throw in circuits."},"warnings":[{"fix":"Ensure your ESLint config uses parser: '@typescript-eslint/parser' and enable TypeScript parsing.","message":"Plugin only works with TypeScript projects using @typescript-eslint/parser. Plain JavaScript is not supported.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Move constructor logic to a @method or use a deployment pattern that does not override the constructor.","message":"Plugin enforces that SmartContract constructor cannot be overridden. This may break existing code that defines custom constructors.","severity":"breaking","affected_versions":">=0.4.0"},{"fix":"Use 'plugin:o1js/recommended' and avoid referencing individual rules by name unless necessary.","message":"In future versions, rules may be renamed or removed. The 'recommended' config is the stable path forward.","severity":"deprecated","affected_versions":">=0.4.0"},{"fix":"Manually verify that total internal state objects do not exceed 8, including those without @state decorator.","message":"State variable limit rule checks only the number of @state decorated properties. Non-decorated properties are not counted but may still cause issues.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Avoid using computed property names or dynamic method calls in circuit methods.","message":"ESLint plugin does not detect dynamic method calls (e.g., this['someMethod']()) in circuits; only static analysis is performed.","severity":"gotcha","affected_versions":">=0.1.0"}],"env_vars":null,"last_verified":"2026-05-01T00:00:00.000Z","next_check":"2026-07-30T00:00:00.000Z","problems":[{"fix":"Run 'npm install eslint-plugin-o1js --save-dev' or the equivalent for your package manager.","cause":"Plugin not installed or missing from node_modules.","error":"Failed to load plugin 'o1js': Cannot find module 'eslint-plugin-o1js'"},{"fix":"Install '@typescript-eslint/parser' and set 'parser: '@typescript-eslint/parser'' in your ESLint config.","cause":"ESLint is not configured to parse TypeScript.","error":"Parsing error: The keyword 'const' is reserved"},{"fix":"Ensure plugin is listed in 'plugins: [\"o1js\"]' and rule name matches one of the available rules (e.g., 'o1js/no-throw-in-circuit').","cause":"Rule name is incorrect or plugin not loaded properly.","error":"Definition for rule 'o1js/no-throw-in-circuit' was not found"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}