Skip to content

Repository files navigation

BNA UI πŸš€

BNA UI Header

Build Native Apps - A powerful CLI for creating Expo React Native applications with a beautiful UI component library.

✨ Features

  • 🎨 Beautiful UI Components - Pre-built, customizable components with modern design
  • πŸŒ™ Theme Support - Built-in light/dark mode with seamless transitions
  • πŸ“± Expo Router Ready - Complete navigation setup with tab and stack navigation
  • 🎯 TypeScript First - Full TypeScript support with excellent IntelliSense
  • πŸ“¦ Flexible Package Manager - Works with npm, yarn, or pnpm
  • πŸš€ Zero Configuration - Get started in seconds with sensible defaults
  • πŸ”§ Highly Customizable - Easily customize colors, spacing, and components
  • πŸ“² Cross-Platform - Perfect compatibility across iOS and Android
  • ⚑ Performance Optimized - Lightweight and fast components
  • 🎭 Animation Ready - Smooth animations with React Native Reanimated

πŸ“¦ Installation

# Scaffold a new Expo app
npx bna-ui init my-app
cd my-app

# Add components β€” dependencies come along automatically
npx bna-ui add button
npx bna-ui add card input

# Or browse everything interactively
npx bna-ui add

Already have an Expo project? Skip init and run add inside it.

Commands

Command What it does
bna-ui init [name] Scaffold a new Expo app with routing, theming and a tab layout
bna-ui convex [name] Same, plus a Convex backend with auth and OTP email flows
bna-ui add [...names] Add components, with their hooks, theme files and npm deps

Useful flags for add: --overwrite, --dry-run, --yes, --npm / --yarn / --pnpm / --bun, and --registry <url>.

Components are fetched from https://ui.ahmedbna.com/r and cached under ~/.cache/bna-ui, so repeat installs work offline.

🎯 Usage Example

import React from 'react';
import { Button } from '@/components/ui/button';
import { Card } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { View } from '@/components/ui/view';

export default function HomeScreen() {
  return (
    <View style={{ flex: 1, padding: 20 }}>
      <Card>
        <Input placeholder='Enter your email' keyboardType='email-address' />
        <Button
          variant='success'
          onPress={() => console.log('Button pressed!')}
        >
          Get Started
        </Button>
      </Card>
    </View>
  );
}

πŸŒ™ Theme Configuration

Components read colours through the useColor hook, so light and dark work without any per-component wiring:

import { useColor } from '@/hooks/useColor';

const background = useColor('background');
const primary = useColor('primary');

The tokens live in theme/colors.ts, which lands in your project when you add your first component:

// theme/colors.ts
export const Colors = {
  light: {
    background: '#FFFFFF',
    foreground: '#000000',
    card: '#F2F2F7',
    primary: '#007AFF',
    // ... more tokens
  },
  dark: {
    background: '#000000',
    foreground: '#FFFFFF',
    card: '#1C1C1E',
    // ... more tokens
  },
};

Edit that file and every component follows β€” it's your code now.

πŸ“± Platform Support

  • βœ… iOS - Full native iOS support
  • βœ… Android - Full native Android support
  • βœ… Web - Responsive web support
  • βœ… Expo Go - Development with Expo Go
  • βœ… EAS Build - Production builds with EAS

πŸ“‚ Repository

This is a pnpm + Turborepo monorepo.

Path Package What it is
packages/registry @bna-ui/registry Source of truth for every component, hook, theme, demo
packages/cli bna-ui The published CLI
packages/starters @bna-ui/starters init and convex scaffolds
apps/docs β€” Docs site, and the registry at /r/*.json
apps/playground β€” Expo app for developing components

There is exactly one copy of every component: packages/registry/src/components/ui/button.tsx is what the playground renders, what the docs site displays, and what bna-ui add button installs.

πŸ› οΈ Development

Requires Node 20+ and pnpm 10+.

git clone https://github.com/ahmedbna/ui.git bna-ui
cd bna-ui

pnpm install
pnpm build          # every package, in dependency order
pnpm dev            # docs + playground
pnpm test

Working on a component:

pnpm --filter playground ios     # or android / web

Edit packages/registry/src/components/ui/<name>.tsx and the playground hot reloads.

Testing the CLI against unreleased components:

pnpm --filter docs dev
cd /tmp && node ~/bna-ui/packages/cli/bin/bna-ui.js init app && cd app
node ~/bna-ui/packages/cli/bin/bna-ui.js add button --registry http://localhost:3000/r

🀝 Contributing

We welcome contributions! See CONTRIBUTING.md for the full workflow, and CODE_OF_CONDUCT.md.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feat/amazing-feature)
  3. Commit your changes (git commit -m 'feat: add amazing feature')
  4. Push to the branch (git push origin feat/amazing-feature)
  5. Open a Pull Request

πŸ” Security

Found a vulnerability? Please report it privately β€” see SECURITY.md.

πŸ“„ License

MIT β€” see LICENSE.

πŸ”— Links

⭐ Support

If you find BNA UI helpful, please consider giving it a star on GitHub! It helps us a lot.

GitHub stars

πŸ“ˆ Stats

GitHub package.json version npm npm GitHub


Made with ❀️ by Ahmed BNA

About

BNA UI - Expo, React Native components library

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages