Idomatic
Idomatic is a CLI tool that automatically injects id attributes into your HTML/JSX/TSX/Vue/Angular components.
It helps ensure better testability, maintainability, and traceability in your codebase by adding stable, unique id attributes where they’re missing.
Why Idomatic?
The Problem
When writing frontend code, developers often forget to add id attributes to elements. This causes problems when:
- Writing E2E tests - Selectors like
.btn-primaryare fragile and break when styles change - Debugging - Finding elements in DevTools is harder without meaningful identifiers
- Accessibility - Labels need
forattributes that reference element IDs - Analytics - Tracking tools need stable identifiers for click tracking
The Solution
Idomatic automatically scans your codebase and adds id attributes to elements that don’t have them. It’s:
- Non-destructive - Only adds IDs where missing, never modifies existing ones
- Configurable - Customize prefix, attribute name, excluded tags, and more
- Framework-agnostic - Works with React, Vue, Angular, and plain HTML
Installation
To install Idomatic, run the initializer:
npm init @idomaticThis command will:
- Ask you which framework you’re using (React, Vue, Angular, HTML)
- Create a
.idomatic.config.jsonconfiguration file - Add recommended scripts to your
package.json
Manual Installation
If you prefer manual setup:
npm install -D @idomatic/coreThen create .idomatic.config.json in your project root.
Quick Start
1. Initialize
npm init @idomatic2. Preview Changes (Dry Run)
npx idomatic scan --dryThis shows which files would be modified without actually changing them.
3. Apply Changes
npx idomatic scanThis scans your files and injects missing id attributes.
CLI Commands
idomatic scan
Scans your files and injects missing id attributes based on your config.
npx idomatic scanOptions:
| Flag | Description |
|---|---|
--dry | Preview changes without modifying files |
--verbose | Show detailed output |
idomatic scan --dry
Dry run mode – logs which files would be updated, but doesn’t write anything to disk.
npx idomatic scan --dryThis is useful for:
- CI/CD pipelines to check for missing IDs
- Previewing changes before applying them
- Testing your configuration
Configuration
Idomatic uses a .idomatic.config.json config file to customize how and where IDs are applied.
Full Configuration Example
{
"prefix": "auto-id-",
"attributeName": "id",
"includeExtensions": ["js", "jsx", "ts", "tsx", "html", "vue"],
"excludeFiles": ["node_modules", "dist", "build", ".next"],
"excludeTags": ["html", "head", "meta", "link", "script", "style", "br", "hr"]
}Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
prefix | string | "idomatic-" | Prefix added before generated UUIDs |
attributeName | string | "id" | Attribute to inject (id, data-testid, data-cy, etc.) |
includeExtensions | string[] | ["html"] | File extensions to scan |
excludeFiles | string[] | ["node_modules"] | Directories or files to ignore (supports glob patterns) |
excludeTags | string[] | ["html", "head"] | HTML tags that should be skipped |
Configuration Examples
React/JSX Project
{
"prefix": "app-",
"attributeName": "id",
"includeExtensions": ["jsx", "tsx"],
"excludeFiles": ["node_modules", "dist", ".next", "__tests__"],
"excludeTags": ["html", "head", "meta", "link", "script", "style"]
}Vue Project
{
"prefix": "vue-",
"attributeName": "id",
"includeExtensions": ["vue"],
"excludeFiles": ["node_modules", "dist"],
"excludeTags": ["html", "head", "meta", "link", "script", "style", "template"]
}Angular Project
{
"prefix": "ng-",
"attributeName": "id",
"includeExtensions": ["html"],
"excludeFiles": ["node_modules", "dist", "e2e"],
"excludeTags": ["html", "head", "meta", "link", "script", "style", "ng-container", "ng-template"]
}Using data-testid (for Testing)
{
"prefix": "test-",
"attributeName": "data-testid",
"includeExtensions": ["jsx", "tsx"],
"excludeFiles": ["node_modules"],
"excludeTags": ["html", "head", "script", "style"]
}Using data-cy (for Cypress)
{
"prefix": "",
"attributeName": "data-cy",
"includeExtensions": ["jsx", "tsx", "vue"],
"excludeFiles": ["node_modules", "cypress"],
"excludeTags": ["html", "head", "script", "style"]
}Framework Guides
React / JSX / TSX
Idomatic works seamlessly with React components:
Before:
function LoginForm() {
return (
<form>
<input type="email" placeholder="Email" />
<input type="password" placeholder="Password" />
<button type="submit">Login</button>
</form>
);
}After:
function LoginForm() {
return (
<form id="auto-id-a1b2c3">
<input id="auto-id-d4e5f6" type="email" placeholder="Email" />
<input id="auto-id-g7h8i9" type="password" placeholder="Password" />
<button id="auto-id-j0k1l2" type="submit">Login</button>
</form>
);
}Vue
Idomatic processes Vue Single File Components (.vue files):
Before:
<template>
<div class="card">
<h2>{{ title }}</h2>
<p>{{ description }}</p>
<button @click="handleClick">Action</button>
</div>
</template>After:
<template>
<div id="auto-id-m3n4o5" class="card">
<h2 id="auto-id-p6q7r8">{{ title }}</h2>
<p id="auto-id-s9t0u1">{{ description }}</p>
<button id="auto-id-v2w3x4" @click="handleClick">Action</button>
</div>
</template>Angular
For Angular, Idomatic processes external HTML template files:
Before (component.html):
<div class="container">
<h1>{{ heading }}</h1>
<input [(ngModel)]="searchTerm" placeholder="Search...">
<button (click)="onSearch()">Search</button>
</div>After:
<div id="auto-id-y5z6a7" class="container">
<h1 id="auto-id-b8c9d0">{{ heading }}</h1>
<input id="auto-id-e1f2g3" [(ngModel)]="searchTerm" placeholder="Search...">
<button id="auto-id-h4i5j6" (click)="onSearch()">Search</button>
</div>Note: Make sure your Angular components use templateUrl to reference external HTML files.
Plain HTML
Before:
<section class="hero">
<h1>Welcome</h1>
<p>This is the hero section</p>
<a href="/signup" class="btn">Get Started</a>
</section>After:
<section id="auto-id-k7l8m9" class="hero">
<h1 id="auto-id-n0o1p2">Welcome</h1>
<p id="auto-id-q3r4s5">This is the hero section</p>
<a id="auto-id-t6u7v8" href="/signup" class="btn">Get Started</a>
</section>CI/CD Integration
GitHub Actions
Add Idomatic to your CI pipeline to ensure all new code has proper IDs:
name: Check IDs
on: [push, pull_request]
jobs:
check-ids:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
- run: npm ci
- run: npx idomatic scan --dryThe --dry flag will exit with a non-zero code if any files would be modified, failing the CI check.
Pre-commit Hook
Use Husky to run Idomatic before each commit:
npm install -D husky
npx husky init
echo "npx idomatic scan" > .husky/pre-commitBest Practices
1. Use Meaningful Prefixes
Choose a prefix that identifies your project or component:
{
"prefix": "myapp-"
}2. Exclude Test Files
Don’t add IDs to test files:
{
"excludeFiles": ["__tests__", "*.test.tsx", "*.spec.ts"]
}3. Use data-testid for Testing
If you’re using Testing Library, use data-testid:
{
"attributeName": "data-testid"
}4. Run Dry Mode First
Always preview changes before applying:
npx idomatic scan --dry5. Add to CI/CD
Ensure all new code has IDs by adding Idomatic to your pipeline.
Troubleshooting
IDs not being added
- Check that your file extension is in
includeExtensions - Verify the file isn’t in
excludeFiles - Make sure the tag isn’t in
excludeTags
Existing IDs being overwritten
Idomatic never overwrites existing IDs. If you’re seeing this, check if:
- The element truly had an ID before
- You’re looking at the correct file
Config not being read
Make sure .idomatic.config.json is in your project root (same level as package.json).
Package Scripts
Add these scripts to your package.json for convenience:
{
"scripts": {
"ids": "idomatic scan",
"ids:check": "idomatic scan --dry",
"ids:verbose": "idomatic scan --verbose"
}
}Then run:
npm run ids # Apply IDs
npm run ids:check # Preview changesFAQ
Does Idomatic modify existing IDs?
No. Idomatic only adds IDs to elements that don’t already have one.
Can I use a custom attribute like data-testid?
Yes! Set attributeName in your config:
{
"attributeName": "data-testid"
}Does it work with TypeScript?
Yes. Idomatic supports .ts and .tsx files.
Is it safe to run on production code?
Yes. We recommend using --dry first to preview changes. Idomatic is non-destructive.
How are IDs generated?
IDs are generated using UUIDs prefixed with your configured prefix.
Support
- GitHub Issues: Report a bug 
- GitHub Discussions: Ask a question 
- Email: amarsmajlovic27@gmail.com