React Doctor
makeplane/plane
Scans React code for lint, accessibility, bundle size and architecture issues, reports a health score and checks that changes do not lower it.
Core entry-point router, orchestrator, and reference manual for all Atomico.js tasks.
$ npx skills add atomicojs/atomico --skill atomico -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install atomicojs/atomico atomico --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/atomicojs/atomico.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/atomico .claude/skills/atomico && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "atomico" agent skill from https://github.com/atomicojs/atomico/tree/master/.agents/skills/atomico into .claude/skills/atomico/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "atomico", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/atomicojs/atomico/tree/master/.agents/skills/atomicoType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add atomicojs/atomico --skill atomico -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install atomicojs/atomico atomico --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/atomicojs/atomico.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.agents/skills/atomico .agents/skills/atomico && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "atomico" agent skill from https://github.com/atomicojs/atomico/tree/master/.agents/skills/atomico into .agents/skills/atomico/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "atomico", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add atomicojs/atomico --skill atomico -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install atomicojs/atomico atomico --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/atomicojs/atomico.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.agents/skills/atomico .cursor/skills/atomico && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "atomico" agent skill from https://github.com/atomicojs/atomico/tree/master/.agents/skills/atomico into .cursor/skills/atomico/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "atomico", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/atomicojs/atomico.git --path .agents/skills/atomico--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add atomicojs/atomico --skill atomico -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install atomicojs/atomico atomico --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/atomicojs/atomico.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.agents/skills/atomico .gemini/skills/atomico && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "atomico" agent skill from https://github.com/atomicojs/atomico/tree/master/.agents/skills/atomico into .gemini/skills/atomico/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "atomico", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install atomicojs/atomico atomicoInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add atomicojs/atomico --skill atomico -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/atomicojs/atomico.git skills-src && mkdir -p .github/skills && cp -r skills-src/.agents/skills/atomico .github/skills/atomico && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "atomico" agent skill from https://github.com/atomicojs/atomico/tree/master/.agents/skills/atomico into .github/skills/atomico/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "atomico", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add atomicojs/atomico --skill atomico -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install atomicojs/atomico atomico --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/atomicojs/atomico.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.agents/skills/atomico .opencode/skills/atomico && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "atomico" agent skill from https://github.com/atomicojs/atomico/tree/master/.agents/skills/atomico into .opencode/skills/atomico/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "atomico", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
atomicoCore entry-point router, orchestrator, and reference manual for all Atomico.js tasks.
Atomico is an agent skill from atomicojs/atomico. Core entry-point router, orchestrator, and reference manual for all Atomico.js tasks. Contains coding standards, API cheat sheets, architectural guidelines, and validation rules.
Its SKILL.md is about 4.8k tokens, which your agent loads only when the skill is triggered. The skill folder holds 14 other files (for example `examples/1-properties.md`, `examples/2-states.md` and `examples/3-forms.md`). Compatibility notes: Atomico =2.0, TypeScript =5.0
It sits in Frontend & Design, covering Code quality. The repository describes itself as: Atomico a micro-library for creating webcomponents using only functions, hooks and virtual-dom. The licence is MIT.
7 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit fc10409. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
npxFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use npx, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Atomico >=2.0, TypeScript >=5.0
From compatibility in the SKILL.md frontmatter.
Atomico loads about 4.8k tokens when it runs. Until then it costs about 47 tokens; SKILL.md has 866 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from atomicojs/atomico at commit fc10409, republished under its MIT licence (© atomicojs). 866 words, ~4,812 tokens.
.claude/skills/atomico/SKILL.md (or your agent's skills folder). This skill also uses 12 other files; get the full folder from GitHub.Unified reference for building, auditing, and validating Atomico.js web components.
AGENT CONTRACT: You may not respond to a code generation request without completing the Validation Report in §7. If any check fails, fix the code before responding — do not report failures as acceptable output.
Every Atomico component is defined with c() and must return a <host> root element.
import { c, useProp, css } from "atomico";
export const MyCounter = c(
({ label }) => {
const [value, setValue] = useProp<number>("value");
return (
<host shadowDom>
<button onclick={() => setValue(value + 1)}>
{label}: {value}
</button>
</host>
);
},
{
props: {
label: { type: String, value: () => "Increment" },
size: {
type: String,
reflect: true,
value: (): "normal" | "small" => "normal"
},
value: { type: Number, value: () => 0 }
},
styles: css`
:host {
--font-size: 1em;
}
:host([size="small"]) {
--font-size: 0.5em;
}
`
}
);components/ folder.customElements.define inside the component file. Centralize all registrations in an index file.// components/index.ts <- the ONLY place where elements are registered
import { MyCounter } from "./my-counter.js";
customElements.define("my-counter", MyCounter);// Valid constructors for the `type:` field in props
type AtomicoPropType =
| StringConstructor // type: String
| NumberConstructor // type: Number
| BooleanConstructor // type: Boolean
| ArrayConstructor // type: Array -> requires value: (): T[] => []
| ObjectConstructor // type: Object -> requires value: (): T => ({...})
| MapConstructor
| SetConstructor
| PromiseConstructor
| (new (...args: any[]) => HTMLElement); // HTMLElement or any subclass
// Short form - prop without default or reflect
type PropShorthand = AtomicoPropType;
// Long form - prop with default or reflect
interface PropConfig<T> {
type: AtomicoPropType;
value?: () => T; // MUST be a factory callback - never a static value
reflect?: boolean; // only String | Number | Boolean
}Use the simplest form that satisfies the requirement:
props: {
// Shorthand: no default, no reflect
label: String,
// Config object: only when a default value is needed
count: { type: Number, value: () => 0 },
// Reflect: only to control CSS via attribute selectors
variant: { type: String, reflect: true, value: (): "primary" | "danger" => "primary" }
}Forbidden:
props: {
name: { type: String }, // Verbose config with no default or reflect - use shorthand
count: { type: Number, value: 0 } // Static value - must be a factory callback
}
// Manual type on destructured render argument:
// ({ label }: { label: string }) => ... Atomico infers types automatically from props blockWithout an explicit return type, TypeScript resolves Array to never[] and Object to {}.
Annotate the factory return type to guarantee correct inference in TSX:
interface Option { value: string; label: string; }
interface Config { theme: "light" | "dark"; debug: boolean; }
props: {
// Return type annotation on the factory - inferred as Option[] in TSX
options: { type: Array, value: (): Option[] => [] },
config: { type: Object, value: (): Config => ({ theme: "light", debug: false }) }
}reflect: true is only for visual / CSS states. Allowed types: String, Number, Boolean.
props: {
disabled: { type: Boolean, reflect: true },
variant: { type: String, reflect: true, value: () => "primary" }
},
styles: css`
:host([disabled]) { opacity: 0.5; pointer-events: none; }
:host([variant="danger"]) { background: red; }
`Never use reflect: true on Array or Object — it triggers expensive DOM serialization.
// event<Detail>() - Fire-and-Forget
// Name WITHOUT "on" prefix. The JSX consumer receives it as "on<propName>"
// Calling props.myEvent(detail) dispatches CustomEvent with event.detail = detail
declare function event<Detail = void>(options?: {
bubbles?: boolean;
composed?: boolean;
cancelable?: boolean;
}): EventDescriptor<Detail>;
// callback<Fn>() - Request-Response
// Fn MUST NOT return void - if no return value is needed, use event() instead
declare function callback<
Fn extends (...args: any[]) => NonNullable<unknown>
>(): Fn | undefined;export const ActionButton = c(
(props) => (
<host>
<button onclick={() => props.action({ id: 42 })}>Fire</button>
</host>
),
{
props: {
// No "on" prefix - Atomico maps it as "onaction" automatically in JSX
action: event<{ id: number }>({ bubbles: true, composed: true })
}
}
);Shadow DOM boundary rule: Native events like
changeandsubmithavecomposed: falseand cannot cross the Shadow DOM boundary. Always declare a customevent()with{ bubbles: true, composed: true }and dispatch it explicitly.
export const UiSelect = c(
({ change, options }) => (
<host shadowDom>
<select onchange={(e) => change(e.currentTarget.value as string)}>
{options.map((o) => (
<option value={o.value}>{o.label}</option>
))}
</select>
</host>
),
{
props: {
options: {
type: Array,
value: (): { value: string; label: string }[] => []
},
change: event<string>({ bubbles: true, composed: true })
}
}
);export const TextEditor = c(
({ content, save }) => (
<host shadowDom>
<button
onclick={async () => {
if (save) {
const ok = await save(content);
if (ok) console.log("Saved!");
}
}}
>
Save
</button>
</host>
),
{
props: {
content: { type: String, value: () => "" },
// callback MUST return a value - if no return is needed, use event() instead
save: callback<(content: string) => Promise<boolean>>()
}
}
);Forbidden:
// "on" prefix in event or callback name
props: {
onChange: event();
} // Atomico treats "on*" props as native event subscriptions
// callback returning void - use event() instead
props: {
save: callback<() => void>();
}
// Re-dispatching native events that already bubble
const dispatchInput = useEvent("input"); // "input" already bubbles causes double-fire// Signature reference
declare function useProp<T>(name: string): [T, (val: T) => void];
declare function useState<T>(init: T | (() => T)): [T, (val: T) => void];
declare function useObjectState<T extends object>(
init: T
): [T, (partial: Partial<T>) => void];Does the state need to be read from outside (parent / CSS)?
+- YES -> declare it in props
| +- Does the child also write to it? -> useProp<T>()
| +- Read-only? -> direct destructuring ({ myProp })
+- NO -> private state
+- Single value (boolean, string)? -> useState
+- Two or more related values? -> useObjectState<T>// Read-only prop - direct destructuring, full auto-inference
export const Badge = c(
({ label, variant }) => (
<host shadowDom>
<span class={variant}>{label}</span>
</host>
),
{
props: {
label: String,
variant: { type: String, reflect: true, value: () => "info" }
}
}
);
// Internally mutable prop - useProp with explicit generic
export const Counter = c(
({ label }) => {
const [count, setCount] = useProp<number>("count");
return (
<host>
<button onclick={() => setCount(count + 1)}>
{label}: {count}
</button>
</host>
);
},
{
props: {
label: String,
count: { type: Number, value: () => 0 }
}
}
);
// Grouped private state - useObjectState
export const SearchBar = c(() => {
const [state, setState] = useObjectState({ query: "", filter: "all" });
return (
<host shadowDom>
<input
value={state.query}
oninput={(e) =>
setState({ query: e.currentTarget.value as string })
}
/>
</host>
);
});Forbidden:
// useProp for read-only - use direct destructuring instead
const [label] = useProp("label");
// Multiple useState for related values - use useObjectState
const [query, setQuery] = useState("");
const [filter, setFilter] = useState("all");
// useMemo on small lists - direct computation is cheaper
const filtered = useMemo(() => items.filter(isActive), [items]);
// Correct:
const filtered = items.filter(isActive);
const done = items.length - filtered.length; // math deduction, no second iterationThe TSX compiler automatically infers the event target type when handlers are inline.
// With inline handler, Atomico JSX infers automatically:
// oninput -> e: { currentTarget: HTMLInputElement }
// onchange -> e: { currentTarget: HTMLSelectElement }
// e.currentTarget.value -> string | number requires `as string` when passing to setState// Inline: e.currentTarget typed as HTMLInputElement - zero manual castings
<input oninput={(e) => setState({ query: e.currentTarget.value as string })} />;
// Extracted: forces `any`, breaks auto-inference
const handleInput = (e: any) => setState({ query: e.currentTarget.value });
<input oninput={handleInput} />;Rule: Single-use handlers go inline. Extract only if the exact same function is shared across multiple elements.
useRef — no null initializationdeclare function useRef<T>(): { current: T | undefined };// Parameterless - typed as T | undefined, no null needed
const inputRef = useRef<HTMLInputElement>();
if (inputRef.current) inputRef.current.focus(); // guard is mandatory
// Reference to another Atomico constructor
const btnRef = useRef<typeof MyButton>();useListener — prefer over manual addEventListener// Automatic cleanup on unmount, no useEffect boilerplate needed
useListener(containerRef, "keydown", (e) => {
if (e.key === "Enter") handleSubmit();
});
// Manual addEventListener inside useEffect - forbidden
useEffect(() => {
const el = containerRef.current;
el?.addEventListener("keydown", handler);
return () => el?.removeEventListener("keydown", handler);
}, []);Atomico JSX maps attribute values differently from standard React/DOM types:
// TS2345: currentTarget.value is string | number in Atomico JSX
oninput={(e) => setState({ title: e.currentTarget.value })}
// Force to string:
oninput={(e) => setState({ title: e.currentTarget.value as string })}
// TS2322: input value may be string | number
<input value={form.count} />
// Force to string:
<input value={String(form.count)} />
// TS2352: e.target is DOMFormElements, not HTMLFormElement
const form = e.target as HTMLFormElement;
// Pass through unknown:
const form = e.target as unknown as HTMLFormElement;When a child component's constructor is imported in the file, always use it as a PascalCase tag:
import { TodoItem } from "./todo-item.js";
// Imported constructor -> PascalCase -> automatic prop types and autocompletion
<TodoItem title="Task" completed={false} />
// String tag bypasses type checking entirely
<todo-item title="Task" />Fallback: kebab-case string tags are allowed only when the constructor is not accessible in the current file (native HTML elements, globally registered third-party elements).
c(render, config): ConstructorDefines the web component constructor. The render function receives props and must return <host>.
css: CSSResult (tagged template)Tagged template literal for styles encapsulated in Shadow DOM. -> example
useProp<T>(name: string): [T, (val: T) => void]Reads and writes a declared prop from inside the component. Use only when the component needs to mutate the value internally. -> example
useState<T>(init: T | (() => T)): [T, (val: T) => void]Single ephemeral private state. Use only for one isolated boolean/string toggle. -> example
useObjectState<T extends object>(init: T): [T, (partial: Partial<T>) => void]Grouped private state with partial updates. Use when managing 2+ related values. -> example
event<Detail>(opts?): EventDescriptor<Detail>Declares a Fire-and-Forget CustomEvent dispatcher in props. Name WITHOUT "on" prefix.
-> example
callback<Fn extends (...args) => NonNullable<unknown>>(): Fn | undefinedDeclares a Request-Response callback prop. Fn must never return void.
-> example
useEvent<Detail>(name: string, opts?: EventInit): (detail?: Detail) => voidDispatches a CustomEvent from within component logic or a custom hook. -> example
useListener(ref, type: string, callback, opts?: AddEventListenerOptions): voidSubscribes to DOM events on a ref. Handles cleanup automatically on unmount. -> example
useRef<T>(): { current: T | undefined }Persistent mutable reference to a DOM node or constructor. No null initialization needed. -> example
useEffect(fn: () => void | (() => void), deps?): voidExecutes side effects asynchronously after render/paint.
useMemo<T>(fn: () => T, deps: any[]): TCaches expensive computations. Do not use for simple operations on small collections. -> example
useSlot(ref): Element[]Tracks elements assigned to a <slot>. Triggers re-render on slot changes.
-> example
useNodes(filter?): Node[]Observes Light DOM children directly via MutationObserver. -> example
useParent<T>(target, crossShadow?: boolean): T | undefinedTraverses DOM ancestors. Set crossShadow = true to cross Shadow DOM boundaries.
-> example
useInternals(): ElementInternalsAccesses the native ElementInternals instance. Requires form: true in config.
-> example
useFormProps(): [value, setFormValue]Auto-syncs name and value properties with the parent FormData.
-> example
useFormValidity(check: () => string | void, deps?): voidIntegrates native browser constraint validation into form-associated components. -> example
usePromise<T>(fn: () => Promise<T>, deps?): [T | undefined, "pending" | "fulfilled" | "rejected"]Resolves and tracks a local promise. The component owns the async lifecycle. -> example
useAsync<T>(fn, deps?): [T | undefined, "pending" | "fulfilled" | "rejected"]Manages async operations controlled by parent elements. -> example
useSuspense(promise: Promise<any>): voidSuspends rendering until the given promise resolves. -> example
useHost<T>(): { current: T }Returns a ref pointing directly to the component's host element. -> example
useUpdate(): () => voidReturns a function that forces an imperative re-render of the element. -> example
Before marking any task as complete, run this two-phase audit.
| # | Check | Reject if... |
|---|---|---|
| 1 | PascalCase constructors in JSX | imported constructor used as kebab-case tag |
| 2 | Inline single-use handlers | handler extracted to a local const handleX = ... variable |
| 3 | No void callbacks | callback<() => void>() found in props |
| 4 | No manual prop types | ({ x }: { x: string }) => found in render signature |
| 5 | useListener over addEventListener | manual addEventListener inside useEffect on a ref |
Fail fast: if any check above fails, report the violation immediately and skip Phase 2.
npx tsc -p tsconfig.json --noEmit --noErrorTruncation > tmp/tsc-errors.log 2>&1tsconfig.json exists, generate a fallback targeting ["src/**/*", "types/**/*"].tmp/tsc-errors.log and send the complete error list to the Developer.After every code generation, append this block to the response:
### Validation Report
- [ ] All handlers are inline (no extracted const handleX)
- [ ] Imported constructors use PascalCase in JSX
- [ ] No callback<() => void> in props
- [ ] Array/Object props have return-type annotation
- [ ] tsc: `npx tsc --noEmit` -> PASS / FAIL - [error summary if FAIL]© atomicojs, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 12 other files in .agents/skills/atomico of atomicojs/atomico.
Open the folder on GitHubat commit fc10409
Atomico next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Atomico this skillatomicojs/atomico | 1.3k | — | ~4.8k | Automated safety check: Pass | MIT | |
| React Doctormakeplane/plane | 60k | 12 repos | ~657 | Automated safety check: Pass | AGPL-3.0 | |
| Frontend Module Standardssiteboon/claudecodeui | 14k | — | ~2.6k | Automated safety check: Pass | AGPL-3.0 | |
| Standards Kitwednesday-solutions/ai-agent-skills | 170 | — | ~436 | Automated safety check: Pass | MIT | |
| Tabler Backward Compatibilitytabler/tabler | 42k | — | ~4k | Automated safety check: Pass | MIT | |
| Best Practicestech-leads-club/agent-skills | 7k | — | ~3.2k | Automated safety check: Pass | MIT |
makeplane/plane
Scans React code for lint, accessibility, bundle size and architecture issues, reports a health score and checks that changes do not lower it.
siteboon/claudecodeui
Enforces one repository's React and TypeScript module layout for code under src/: source-root imports, feature barrels, deliberate exports and no deep imports.
wednesday-solutions/ai-agent-skills
Unified development and design standards. An agent skill from wednesday-solutions/ai-agent-skills.
tabler/tabler
Keeps changes to @tabler/core backward compatible so patch and minor releases never break projects, covering what counts as public API and how to alias renames.
tech-leads-club/agent-skills
Apply modern web development best practices for security, compatibility, and code quality.
Asymmetric-al/core
Installs and runs Million's React Doctor to audit a React or Next.js codebase for performance, security, correctness, and architecture issues.
Categories
Core entry-point router, orchestrator, and reference manual for all Atomico.js tasks. Atomico is an agent skill from atomicojs/atomico.js tasks.
Atomico fits situations like: tasks that involve Code quality.
Run `npx skills add atomicojs/atomico --skill atomico -a claude-code`. Or copy the skill folder (.agents/skills/atomico in atomicojs/atomico) into .claude/skills/atomico in your project. Claude Code loads it when a task matches its description.
Run `npx skills add atomicojs/atomico --skill atomico -a codex`. Or copy the skill folder (.agents/skills/atomico in atomicojs/atomico) into .agents/skills/atomico in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add atomicojs/atomico --skill atomico -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/atomico, .gemini/skills/atomico, .github/skills/atomico and .opencode/skills/atomico in your project.
Going by SKILL.md and its folder, Atomico needs the command-line tools its instructions call (npx). Compatibility (from SKILL.md): Atomico >=2.0, TypeScript >=5.0.
SKILL.md contains no URLs. Its commands use npx, which can reach the network depending on how they are called. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Atomico is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.
About 4.8k tokens (SKILL.md is roughly 19k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Atomico: React Doctor (makeplane/plane, 60k stars), Frontend Module Standards (siteboon/claudecodeui, 14k stars), Standards Kit (wednesday-solutions/ai-agent-skills, 170 stars) and Tabler Backward Compatibility (tabler/tabler, 42k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
atomicojs (a GitHub organization) maintains it in atomicojs/atomico, which has 1,280 GitHub stars. The repository was last updated on July 19, 2026.
Source: atomicojs/atomico on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.