DEV Community

Cover image for Building a Football Formation Component for React Native ⚽
Arbab Rafiq
Arbab Rafiq

Posted on

Building a Football Formation Component for React Native ⚽

As a football enthusiast and React Native developer, I've always been fascinated by the tactical side of the beautiful game. Whether it's analyzing how Guardiola's 4-3-3 differs from Klopp's setup or understanding why a 3-5-2 might counter a 4-2-3-1, formations tell a story.

But when I needed to display team lineups in a mobile app, I hit a wall. There was no ready-made React Native component that could elegantly render football formations with player statistics, custom styling, and proper TypeScript support.

So I built one. And today, I'm sharing the journey of creating react-native-football-formation — a package that's now available on npm for the entire React Native community.


🎯 The Problem: Visualizing Tactical Complexity

If you've ever tried to build a football app, you know the challenge. A team formation isn't just a static image, it's a dynamic visualization that needs to:

  • Position 11 players accurately based on tactical formation (4-3-3, 4-2-3-1, 5-3-2, etc.)
  • Display player statistics (goals, assists, cards, substitutions)
  • Handle multiple formations (there are dozens of tactical setups)
  • Support customization (team colors, fonts, icons)
  • Work on different screen sizes and orientations
  • Provide excellent TypeScript support for developer experience

The existing solutions were either too rigid, poorly maintained, or simply didn't exist for React Native. Most developers were either embedding static images or building one-off custom solutions for each project.

I wanted something better, a flexible, production-ready component that any developer could drop into their app.

demo


💡 The Solution: A Highly Customizable Formation Component

After weeks of development, testing, and iteration, here's what I built:

import { FormationField } from 'react-native-football-formation';

function MatchLineup() {
  const lineup = {
    players: [
      {
        playerId: '1',
        matchName: 'De Gea',
        shirtNumber: 1,
        rating: '7.5',
        position: 'Goalkeeper',
        formationPlace: '1',
        stats: [
          { type: 'goals', value: 1 },
          { type: 'yellowCard', value: '1' },
        ],
      },
      // ... 10 more players
    ],
    formationUsed: '433',
  };

  return (
    <FormationField
      lineup={lineup}
      getPlayerPhotoUrl={(playerId) =>
        `https://api.example.com/players/${playerId}.png`
      }
      onPlayerPress={(player) => {
        // Navigate to player details
        console.log('Tapped:', player.matchName);
      }}
    />
  );
}
Enter fullscreen mode Exit fullscreen mode

Simple API. Powerful features. That's what I aimed for.


🚀 Key Features That Make It Stand Out

1. Support for 24 Tactical Formations

From the classic 4-4-2 to modern variations like the 3-2-4-1 or false 9 (4-2-4-0), the component handles them all. Each formation has carefully calculated coordinate mappings to position players realistically on the field.

The coordinate system I developed allows for precise positioning:

const playerX = (player.x / 100) * fieldWidth - cardWidth / 2;
const playerY = (player.y / 100) * fieldHeight - cardHeight / 2;
Enter fullscreen mode Exit fullscreen mode

This percentage-based approach ensures formations scale perfectly across different device sizes.

2. Comprehensive Player Statistics

The component automatically renders player stats with intuitive visual indicators:

  • ⚽ Goals scored (with count for multiple goals)
  • 👟 Assists provided
  • 🟨 Yellow cards
  • 🟥 Red cards
  • 🔄 Substitutions
  • ⚽🔴 Own goals

All icons are customizable, and stats gracefully handle null values and zero counts.

3. Complete Theme Customization

Every visual aspect is customizable through a comprehensive theme system:

<FormationField
  lineup={lineup}
  theme={{
    colors: {
      primary: '#FF0000',
      playerName: '#FFFFFF',
      success: '#00FF00',
      warning: '#FFAA00',
    },
    typography: {
      fontFamily: 'MyCustomFont-Regular',
      fontFamilyBold: 'MyCustomFont-Bold',
      playerNameSize: 14,
    },
    spacing: {
      playerCardWidth: 80,
      playerImageSize: 50,
    },
  }}
/>
Enter fullscreen mode Exit fullscreen mode

4. RTL Language Support 🌍

Being conscious of the global football community, I built in full RTL (right-to-left) support using React Native's I18nManager. The component automatically adapts icon positioning and text direction for Arabic, Hebrew, and other RTL languages.

5. Custom Rendering Hooks

For advanced use cases, developers can override the default player cards or footer:

<FormationField
  lineup={lineup}
  renderPlayerCard={(player, width, height) => (
    <CustomPlayerCard player={player} />
  )}
  renderFooter={(formation) => (
    <CustomFooter formation={formation} />
  )}
/>
Enter fullscreen mode Exit fullscreen mode

This makes the component incredibly flexible while maintaining ease of use for simple cases.


🔧 Technical Decisions & Challenges

TypeScript First

I wrote the entire package in TypeScript. This was non-negotiable. The type safety not only caught countless bugs during development but also provides an excellent developer experience with full IntelliSense support.

interface Player {
  rating: string;
  playerId: string;
  position: string;
  matchName: string;
  shirtNumber: number;
  formationPlace?: string;
  stats: (PlayerStats | null)[];
}

interface PlayerStats {
  type: 'goals' | 'yellowCard' | 'redCard' | 'goalAssist' | 'totalSubOff' | 'ownGoals';
  value: string | number;
}
Enter fullscreen mode Exit fullscreen mode

Coordinate Calculation Mathematics 📐

Calculating accurate player positions for 24 different formations was mathematically intensive. Each formation needed manual coordinate mapping based on realistic tactical positioning:

export const FORMATION_COORDINATES_BY_PLACE = {
  '4-3-3': {
    '1': { x: 50, y: 90 },  // Goalkeeper
    '2': { x: 20, y: 70 },  // Right Back
    '3': { x: 40, y: 75 },  // Center Back
    // ... positions 4-11
  },
  '4-2-3-1': {
    // Different coordinate mapping
  },
  // ... 22 more formations
};
Enter fullscreen mode Exit fullscreen mode

I spent hours watching match footage and analyzing tactical diagrams to get these positions right.

Performance Optimization ⚡

With 11 player cards, each containing multiple conditional renderings (stats icons, cards, etc.), performance was critical. I implemented:

  • React.memo for PlayerCard component to prevent unnecessary re-renders
  • Conditional rendering to only show stat icons when they exist
  • Optimized image loading with proper resize modes
  • Efficient coordinate calculations cached at the component level

💼 Real-World Use Cases

The package is versatile enough for various applications:

  • Fantasy Football Apps: Display user lineups with live player stats
  • Sports News Apps: Visualize team formations in match previews
  • Tactical Analysis Tools: Allow coaches to create and share formations
  • Match Statistics Apps: Show starting elevens with performance metrics
  • Football Games: Display team selection screens

🎮 Try It Yourself

The package is available now on npm:

npm install react-native-football-formation
Enter fullscreen mode Exit fullscreen mode

Or if you prefer yarn:

yarn add react-native-football-formation
Enter fullscreen mode Exit fullscreen mode

React Native Football Formation

A highly customizable React Native component for displaying football/soccer team formations with player positions, stats, and match information.

React Native TypeScript License

Status

Note: This package is currently in active development and is provided for testing and evaluation purposes only. The API is subject to change and stability is not guaranteed. It is not recommended for use in production environments at this time.

Demo

Football Formation Demo

Features

24 Supported Formations - All major tactical formations (4-3-3, 4-2-3-1, 3-5-2, etc.) ✅ Player Statistics - Goals, assists, cards, substitutions, own goals ✅ Highly Customizable - Theme system for colors, fonts, spacing ✅ RTL Support - Built-in support for right-to-left languages ✅ TypeScript - Full type safety and IntelliSense ✅ Expo & Bare RN - Compatible with both Expo and bare React Native projects ✅ Asset Override - Use your own field backgrounds and icons ✅ Component Override - Custom rendering for player cards…


💭 Final Thoughts

Building this package taught me that great developer tools require:

  • Clear problem definition (what specific pain are you solving?)
  • Simple API design (make the easy things easy, hard things possible)
  • Comprehensive documentation (code is only half the product)
  • Community engagement (listen, iterate, improve)
  • Production quality (TypeScript, error handling, edge cases)

Whether you're building a football app or any other specialized component, I hope this journey inspires you to contribute to the open-source ecosystem. The React Native community thrives on developers solving real problems and sharing solutions.


👋 Let's Connect!

If you found this useful, give the repository a ⭐ on GitHub! I'd love to hear:

  • What features would you like to see?
  • Are you building a football/sports app?
  • What challenges have you faced with React Native components?

Drop a comment below and let's chat! 💬

⚽ Happy coding, and may your formations always be tactically sound!


About Me: I'm Arbab Rafiq, a React Native developer passionate about building developer tools and sports applications. Find me on GitHub.

Top comments (0)