Install
$ agentstack add skill-medy-gribkov-arcana-frontend-code-review ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Frontend Code Review
Review Process
This skill reviews .tsx, .ts, and .js files against three categories:
- Code Quality - Consistent patterns, maintainability
- Performance - React rendering optimization
- Business Logic - Domain-specific rules
Two review modes:
- Pending-change review - Scan staged/modified files before commit
- File-targeted review - Review specific files the user names
Code Quality Rules
Rule 1: Conditional Classnames (URGENT)
Requirement: Use cn() utility for all conditional CSS, not ternaries or string concatenation.
BAD:
// Manual ternary
// String concatenation
// Template literal
GOOD:
import { cn } from '@/utils/classnames';
Why urgent: Inconsistent patterns make global style changes difficult.
Rule 2: Tailwind-First Styling (URGENT)
Requirement: Prefer Tailwind utilities over .module.css files unless Tailwind cannot achieve the effect.
BAD:
// styles.module.css
.button {
padding: 0.75rem 1.5rem;
background-color: #3b82f6;
border-radius: 0.5rem;
}
// Component.tsx
import styles from './styles.module.css';
Click
GOOD:
Click
When CSS modules are acceptable:
- Complex animations requiring
@keyframes - Browser-specific hacks
- Third-party library style overrides
Rule 3: ClassName Ordering for Overrides
Requirement: Place incoming className prop AFTER component's own classes.
BAD:
const Button = ({ className }: { className?: string }) => {
return (
{/* Consumer can't override bg-primary-600 */}
);
};
// Consumer tries to change background
{/* Won't work */}
GOOD:
const Button = ({ className }: { className?: string }) => {
return (
{/* className comes LAST, can override */}
);
};
{/* Works */}
Performance Rules
Rule 1: React Flow Data Access (URGENT)
Requirement: Use useNodes/useEdges for UI rendering. Use useStoreApi inside callbacks that mutate state.
BAD:
import useNodes from '@/app/components/workflow/store/workflow/use-nodes';
const NodeComponent = () => {
const nodes = useNodes(); // Wrong hook
// ...
};
GOOD:
import { useNodes, useStoreApi } from 'reactflow';
const NodeComponent = () => {
const nodes = useNodes(); // Correct React Flow hook
const store = useStoreApi();
const handleUpdate = () => {
const { getNodes, setNodes } = store.getState();
// Mutate via store API
};
return {nodes.length} nodes;
};
Why urgent: Using wrong hooks causes blank screens when no workflowStore provider exists.
Rule 2: Complex Prop Memoization (URGENT)
Requirement: Wrap objects, arrays, and functions passed as props in useMemo or useCallback.
BAD:
function ParentComponent() {
return (
console.log('update')}
/>
);
// Every render creates NEW objects/arrays/functions
// Child re-renders even if nothing changed
}
GOOD:
function ParentComponent() {
const config = useMemo(() => ({
apiKey: 'abc',
endpoint: '/api/data'
}), []);
const filters = useMemo(() => ['active', 'recent'], []);
const handleUpdate = useCallback(() => {
console.log('update');
}, []);
return (
);
// Stable references, child only re-renders when props actually change
}
Why urgent: Causes unnecessary re-renders, degrades performance with complex components.
Business Logic Rules
Rule 1: No workflowStore in Node Components (URGENT)
Applies to: Files matching web/app/components/workflow/nodes/[nodeName]/node.tsx
Requirement: Node components cannot import workflowStore because they're used in contexts without the provider.
BAD:
// web/app/components/workflow/nodes/TextNode/node.tsx
import useNodes from '@/app/components/workflow/store/workflow/use-nodes';
export const TextNode = () => {
const nodes = useNodes(); // Breaks when no provider
// ...
};
GOOD:
// web/app/components/workflow/nodes/TextNode/node.tsx
import { useNodes } from 'reactflow';
export const TextNode = () => {
const nodes = useNodes(); // Works in all contexts
// ...
};
Why urgent: Causes blank screens when creating RAG Pipes from templates (no workflowStore provider in that flow).
Review Output Format
Template A: Issues Found
# Code review
Found urgent issues that need to be fixed:
## 1. Using manual ternary instead of cn() utility
FilePath: src\components\Button.tsx line 12
### Suggested fix
Replace with cn() utility:
import { cn } from '@/utils/classnames';
---
## 2. Object prop not memoized
FilePath: src\pages\Dashboard.tsx line 45
### Suggested fix
Wrap in useMemo:
const config = useMemo(() => ({ apiKey: key, url: endpoint }), [key, endpoint]);
---
Found suggestions for improvement:
## 1. Consider using Tailwind instead of CSS module
FilePath: src\components\Card.tsx line 5
import styles from './Card.module.css';
### Suggested fix
Replace CSS module with Tailwind utilities if possible.
---
If >= 10 issues: Show first 10, summarize as "10+ urgent issues".
If any issue requires code changes: End with "Would you like me to apply the suggested fixes?"
Template B: No Issues
## Code review
No issues found.
Example Review Workflow
Step 1: Scan File
// src/components/UserCard.tsx
import { useNodes } from 'reactflow';
import styles from './UserCard.module.css';
export const UserCard = ({ user, className }) => {
const nodes = useNodes();
return (
);
};
Step 2: Identify Violations
- Line 2: Using CSS module (Code Quality, suggestion)
- Line 7: Manual string concatenation instead of
cn()(Code Quality, URGENT) - Line 8: Manual ternary instead of
cn()(Code Quality, URGENT) - Line 9: Object prop not memoized (Performance, URGENT)
Step 3: Generate Report
# Code review
Found 3 urgent issues that need to be fixed:
## 1. Manual string concatenation for classnames
FilePath: src\components\UserCard.tsx line 7
### Suggested fix
Replace with cn() utility:
import { cn } from '@/utils/classnames';
---
## 2. Manual ternary for conditional classname
FilePath: src\components\UserCard.tsx line 8
### Suggested fix
import { cn } from '@/utils/classnames';
---
## 3. Object prop not memoized
FilePath: src\components\UserCard.tsx line 9
### Suggested fix
const data = useMemo(() => ({ id: user.id, name: user.name }), [user.id, user.name]);
---
Found 1 suggestion for improvement:
## 1. Consider Tailwind instead of CSS module
FilePath: src\components\UserCard.tsx line 2
import styles from './UserCard.module.css';
### Suggested fix
Evaluate if CSS module is necessary or if Tailwind utilities can replace it.
---
Would you like me to apply the suggested fixes?
Quick Reference
Urgency Levels:
URGENT: Code Quality violations, Performance issues, Business Logic bugs
SUGGESTION: Best practices, minor improvements
Common Patterns to Flag:
BAD: className={a ? 'x' : 'y'}
GOOD: className={cn(a ? 'x' : 'y')}
BAD:
GOOD: const config = useMemo(() => ({...}), [deps]);
BAD: import useNodes from '@/store/workflow/use-nodes'
GOOD: import { useNodes } from 'reactflow'
Use this skill: Before committing frontend changes, during PR reviews, or when diagnosing rendering performance issues.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: medy-gribkov
- Source: medy-gribkov/arcana
- License: Apache-2.0
- Homepage: https://www.npmjs.com/package/@sporesec/arcana
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.