Architecture enforcement for MVVM patterns in React Native applications.
Install
mkdir -p .claude/skills/mvvm && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/17262" && unzip -o skill.zip -d .claude/skills/mvvm && rm skill.zipInstalls to .claude/skills/mvvm
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Enforce MVVM architecture in React Native/Expo apps, especially screens, hooks as ViewModels, services, and code reviews.Key capabilities
- →Enforce MVVM architecture in React Native/Expo apps
- →Isolate Model, ViewModel, and View layers
- →Define naming conventions for ViewModels
- →Move business logic from components to ViewModels
- →Perform code reviews for MVVM compliance
How it works
The skill enforces the MVVM pattern by defining rules for Model, ViewModel, and View layers, including file locations, naming conventions, and responsibilities. It provides a refactoring checklist to migrate existing code to MVVM.
Inputs & outputs
When to use mvvm
- →Structuring a new React Native screen
- →Moving logic from components to ViewModels
- →Performing code reviews for MVVM compliance
- →Creating domain-specific services
About this skill
MVVM Architecture Skill - React Native / Expo
Purpose
Enforce Model-View-ViewModel (MVVM) pattern across the entire codebase. Every screen and component must separate concerns cleanly.
Layer Definitions
Model (Data Layer)
- Location:
types/,src/services/,src/sync/ - Contains: TypeScript types/interfaces, API clients, AsyncStorage persistence, data transformation
- Rules:
- No React imports
- No UI logic
- Pure functions and async service calls
- One service file per domain entity (e.g.
gruposService.ts,planeacionesService.ts)
ViewModel (Logic Layer)
- Location:
src/hooks/(one file per screen or shared domain) - Naming:
use{ScreenName}ViewModel.ts(e.g.useCrearGrupoViewModel.ts) - Contains: all
useState,useEffect,useCallback,useMemo, derived state, validation, business logic, navigation triggers - Rules:
- Custom hook that returns a typed interface
- No JSX
- No
StyleSheet, no layout logic - May call services, context, other hooks
- Must define a return type interface (e.g.
CrearGrupoViewModel) - All event handlers live here (onSave, onDelete, onChange, etc.)
- Navigation calls go here when triggered by logic (e.g. after save)
View (Presentation Layer)
- Location:
src/screens/,src/components/ - Contains: JSX rendering, StyleSheet, layout
- Rules:
- Call the ViewModel hook at the top:
const vm = useXxxViewModel() - Destructure only what is needed from the ViewModel
- No
useStatefor business state (UI-only state likescrollYormenuVisibleis allowed) - No direct service calls
- No async operations
- No data transformation or validation logic
- Bind ViewModel properties to JSX:
<Text>{vm.title}</Text> - Bind ViewModel handlers to events:
<Button onPress={vm.onSave} />
- Call the ViewModel hook at the top:
ViewModel Template
// src/hooks/useExampleViewModel.ts
import { useState, useCallback } from "react";
import { useNavigation } from "@react-navigation/native";
import type { NativeStackNavigationProp } from "@react-navigation/native-stack";
import type { RootStackParamList } from "../navigation/StackNavigator";
export interface ExampleViewModel {
// State
title: string;
isLoading: boolean;
error: string | null;
// Actions
setTitle: (value: string) => void;
onSave: () => Promise<void>;
}
export const useExampleViewModel = (): ExampleViewModel => {
const navigation =
useNavigation<NativeStackNavigationProp<RootStackParamList>>();
const [title, setTitle] = useState("");
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const onSave = useCallback(async () => {
setIsLoading(true);
try {
// call service
navigation.goBack();
} catch (err) {
setError(String(err));
} finally {
setIsLoading(false);
}
}, [title, navigation]);
return { title, isLoading, error, setTitle, onSave };
};
When This Skill Applies
- Creating any new screen or component
- Modifying any existing screen
- Reviewing pull requests
- Refactoring code
Refactoring Checklist
When modifying a screen that does NOT follow MVVM:
- Create
src/hooks/use{Screen}ViewModel.ts - Move all
useState(except UI-only state) into the ViewModel - Move all
useEffectwith business logic into the ViewModel - Move all handler functions into the ViewModel
- Move all service/context calls into the ViewModel
- Define a typed return interface
- In the screen, call the hook and bind to JSX
- Verify the screen file contains only: JSX, StyleSheet, UI-only state
Exceptions
- Pure navigation screens (no state, just menu cards that navigate): ViewModel is optional if the screen has zero state and zero logic. Still recommended for consistency.
- UI-only state:
menuVisible,scrollPosition,expandedtoggles that control layout can stay in the View. - Shared components (
SemanaEditor,EvaluacionEditor): May keep local UI state for controlled inputs. Business logic should be in the parent ViewModel, passed down as callbacks via props.
File Organization
src/
hooks/
useGrupos.ts
useLoginViewModel.ts
useHomeViewModel.ts
useCrearPlaneacionViewModel.ts
useEditorPlaneacionViewModel.ts
useListaPlaneacionesViewModel.ts
useCrearGrupoViewModel.ts
useListaGruposViewModel.ts
useDetalleGrupoViewModel.ts
useCrearTareaGrupoViewModel.ts
useCalificarEntregasViewModel.ts
useListaRecursosViewModel.ts
useCuentaViewModel.ts
screens/
(Views only - JSX + StyleSheet)
services/
(Model - data access)
types/
(Model - type definitions)
Do Not
- Put
useStatefor domain data inside a screen component - Call services directly from a screen component
- Put navigation logic inside JSX event handlers inline
- Skip the typed return interface on ViewModels
- Name ViewModel files without the
useprefix
When not to use it
- →When `useState` for domain data is inside a screen component
- →When services are called directly from a screen component
- →When navigation logic is inside JSX event handlers inline
Limitations
- →ViewModels must be custom hooks that return a typed interface.
- →Views should not contain `useState` for business state.
- →Models should not contain React imports or UI logic.
How it compares
This skill provides a structured approach to implementing MVVM in React Native/Expo, ensuring clear separation of concerns and maintainability, which is more disciplined than ad-hoc component development.
Compared to similar skills
mvvm side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| mvvm (this skill) | 0 | 19d | No flags | Intermediate |
| react-native-architecture | 55 | 2mo | Review | Advanced |
| react-native-architecture | 0 | 3mo | No flags | Intermediate |
| mobile-state-management-patterns | 0 | 3mo | No flags | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
react-native-architecture
wshobson
Build production React Native apps with Expo, navigation, native modules, offline sync, and cross-platform patterns. Use when developing mobile apps, implementing native integrations, or architecting React Native projects.
react-native-architecture
Anhvu1107
ALWAYS use this when the request matches React Native Architecture: Production-ready patterns for React Native development with Expo, including navigation, state management, native modules, and offline-first architecture.
mobile-state-management-patterns
almasumdev
Comparison of mobile state management patterns (MVVM, MVI, TEA, Redux, BLoC, Observable, Compose state, SwiftUI state) and how to choose. Use when designing state flow or evaluating a state library.
react-native-design
wshobson
Master React Native styling, navigation, and Reanimated animations for cross-platform mobile development. Use when building React Native apps, implementing navigation patterns, or creating performant animations.
agent-spec-mobile-react-native
ruvnet
Agent skill for spec-mobile-react-native - invoke with $agent-spec-mobile-react-native
heroui-native
heroui-inc
HeroUI Native component library for React Native (Tailwind v4 via Uniwind). Use when working with HeroUI Native components, installing HeroUI Native, customizing themes, or accessing component documentation. Keywords: HeroUI Native, heroui-native, React Native UI, Uniwind.