devsplain never rewrites executable code—it's a single-shot CLI that adds JSDoc and inline comments across 22 languages using LLMs, preserving non-comment source lines byte-for-byte through deterministic verification.
Unlike interactive AI editors, devsplain is designed for batch documentation passes, CI pipelines, and git hook automation—no agent overhead, no per-file confirmation loops.
Tip
Built with devsplain
This entire repository is heavily "dogfooded". Every single AI-generated [ds] comment you see in the source code of this tool was automatically generated and committed by devsplain itself using its native git hooks!
- Deterministic Code Integrity Verification: Uses an index-preserving splicing engine. Your non-comment source lines are guaranteed to remain byte-for-byte identical after comment insertion.
- Multi-Language support: Works across JavaScript, JSX, TypeScript, TSX, HTML, CSS, SCSS, Vue, Svelte, Python, Java, C, C++, C#, Go, Ruby, PHP, Rust, Swift, Kotlin, Dart, and Shell scripts.
- Comment Preservation & Tagging: AI-generated comments are tagged with
[ds]. Your manually written comments are safe and will never be touched by the engine. - Local Deterministic Scrubber: The
--cleanflag strips AI-generated[ds]comments locally using a deterministic lexical state machine—no LLM calls, API keys, or internet required. - Git Hook Automation: Supports an automated two-commit Git hook workflow (
pre-commitfor quality,post-commitfor auto-generated documentation commits) that prevents recursive commit loops. - Bring Your Own LLM: Native setup wizard for Groq, Gemini, OpenAI, or any OpenAI-compatible API endpoint (like Ollama or LMStudio).
- Exponential Backoff: Resilient AI request handler that automatically retries rate-limited requests with exponential backoff.
- Headless & Override Control: Configure via environment variables or override global config settings dynamically on the fly with command-line flags.
Many AI code formatters rewrite your code entirely, exposing you to logic regressions and subtle syntax corruption. devsplain is designed from the ground up to prevent this.
- The CLI prepends line numbers to your source code and sends it to the LLM.
- The LLM returns a structured JSON payload containing target line numbers and comment contents:
[ { "line": 12, "comment": "// Calculates the exponential backoff delay" } ] - The splicing engine inserts comments directly into the source array at the requested indices.
- Validation Check: Before writing to disk,
devsplainfilters out the added comments and compares the remaining code lines against your original source. If a single line of executable code has changed, shifted, or been omitted, the process aborts immediately, safeguarding your code from corruption.
The engine tracks lexical state across template strings, single quotes, double quotes, and multi-line docstrings (such as Python triple-quotes). Comment insertion is blocked if the target line resides within a string literal, preventing broken syntax.
Every single comment generated by the LLM is forcibly prefixed with a [ds] tag (e.g., // [ds] This function handles...).
This guarantees that the local devsplain lexer can lexically distinguish between your human-written manual comments and the AI-generated comments.
When you run the --clean command, the lexer looks specifically for the [ds] prefix and surgically removes only the AI-generated comments, safely preserving 100% of your manual documentation.
AST parsers are language-specific. Supporting 22 languages would require 22 native parser dependencies, which defeats the zero-dependency architecture entirely.
The line-splicing + round-trip diff approach achieves equivalent guarantees without any of that bloat. This is not a compromise—it's the right answer for this tool's constraints:
- Original source is loaded.
- Comments are inserted.
- Generated comments are removed.
- The remaining source must match the original file exactly.
If any non-comment source line differs, the operation aborts.
Install globally using npm:
npm install -g devsplainOr run it on demand without installation:
npx devsplain <file-or-directory> [options]On its first run, devsplain launches an interactive configuration wizard to configure your preferred LLM provider.
To force re-run the configuration wizard at any time, execute:
devsplain --configYour settings are stored securely in ~/.devsplainrc (configured with chmod 600 on POSIX systems to restrict read access, and keystrokes are masked during input).
Caution
Security Note: Prefer configuring the DEVSPLAIN_API_KEY environment variable over using the --api-key CLI flag for recurring use. CLI flags may be exposed in your shell history (~/.bash_history) and process lists.
devsplain <file-or-directory> [options]| Flag | Description |
|---|---|
| (Default) | Balanced commenting. Generates a mix of JSDoc block comments above functions and sparse inline comments for complex logical branches. |
--light |
Minimalist commenting. Adds JSDoc/block comments above functions, leaving function bodies untouched. |
--full |
Aggressive commenting. Explains complex logic blocks line-by-line inside functions. |
--dry-run |
Preview comments in the terminal without writing to files. Prompts for manual save confirmation. |
--force |
Bypasses the safety block check that prevents running devsplain on a dirty Git working tree. |
--clean |
Scrubber mode. Deterministically removes only devsplain-generated comments tagged with [ds], preserving your manual comments. |
--prune |
Destructive scrubber mode. Removes ALL comments and docstrings from source files, including your own manual comments. |
--provider <name> |
Temporary one-off override for the AI provider (gemini, groq, openai, custom) for this command run only (does not modify the saved config file). |
--model <name> |
Temporary one-off override for the model name for this command run only. |
--api-key <key> |
Temporary one-off override for the API key for this command run only. |
--base-url <url> |
Temporary one-off override for the API base URL for this command run only. |
--config |
Relaunches the configuration setup wizard. |
--setup-hook |
Installs Git pre-commit and post-commit hooks in the repository. |
--help, -h |
Displays the help menu. |
--version, -v |
Displays version information. |
# Light commenting on a single file
devsplain src/index.js --light
# Deep logic commenting on a folder (skips node_modules, .git, etc.)
devsplain src/ --full
# Clean and scrub AI-generated comments locally without API calls
devsplain lib/ --clean
# Destructively remove ALL comments (both AI and manual) from a folder
devsplain lib/ --prune
# Headless run using overriding credentials
devsplain src/utils.ts --provider gemini --model gemini-2.0-flash --api-key YOUR_KEYTip
Directory Traversal Protection
When you run devsplain on a directory, it automatically ignores common build/dependency folders (node_modules, .git, dist, etc.).
To ignore custom directories, simply create a .devsplainignore file in your project root using the standard .gitignore syntax. (A default .devsplainignore is automatically generated when you run --setup-hook).
For headless environments, CI pipelines, or automated scripts, devsplain respects the following environment variables:
DEVSPLAIN_PROVIDER: Selects the AI provider (groq,gemini,openai,custom).DEVSPLAIN_API_KEY: The API key to use for the selected provider.DEVSPLAIN_MODEL: Specify a custom model.DEVSPLAIN_BASE_URL: Custom base endpoint for local/private API runs.
Ensure all code changes in your repository are automatically documented by configuring Git hooks.
Note
Commit Duration Note
When the Git hooks are enabled, committing code may take a few seconds longer. This is because devsplain needs to call the AI provider, generate comments, and splice them into the modified files before completing the commit cycle.
Run the hook setup command inside your Git repository:
devsplain --setup-hookIf you ever want to commit code without triggering the AI (for example, if you just ran devsplain index.js --full manually and want to freeze those specific comments without the background hook overwriting them), you can bypass the hook entirely:
SKIP_DEVSPLAIN=1 git commit -m "my commit message"(If autoPrune: true is set in your ~/.devsplainrc via the --config wizard, the hook scrubs all existing comments before regenerating them.)
If you want to change this behavior for a specific commit:
- To force an overwrite (destroying all human/AI comments before generating new ones) regardless of your config:
DS_OVER=1 git commit -m "overwrite docs" - To force preservation of existing comments (overriding a global prune preference):
DS_KEEP=1 git commit -m "keep docs"
- Pre-commit Hook: Runs your project test suite (
npm test). If the tests fail, the commit is blocked. - Post-commit Hook:
- Detects all modified files in the commit.
- Runs
devsplainto generate comments on the modified files. - Automatically stages and commits the comments in a secondary commit:
docs: auto-generated comments by devsplain. - The secondary commit runs with
--no-verifyto prevent recursive hook invocation.
- Resilience: If the API key is missing or the network is offline during the post-commit process, the script logs a warning to stderr and exits with status code
0. Your initial commit remains safe and unblocked.
Note
API Testing Notice: devsplain natively supports OpenAI, Anthropic, Ollama, Groq, and Gemini endpoints, but the E2E test suite has currently only been aggressively verified against the Groq and Gemini APIs. If you encounter any unexpected parsing issues or edge-case errors with other providers, please open an issue or submit a PR!
This project is licensed under the MIT License.
